diff --git a/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/consensus/SubmitMessageSuite.java b/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/consensus/SubmitMessageSuite.java index 02475ca8e3c6..d868ebddda83 100644 --- a/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/consensus/SubmitMessageSuite.java +++ b/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/consensus/SubmitMessageSuite.java @@ -17,7 +17,7 @@ package com.hedera.services.bdd.suites.consensus; import static com.hedera.services.bdd.junit.TestTags.ADHOC; -import static com.hedera.services.bdd.spec.HapiSpec.defaultHapiSpec; +import static com.hedera.services.bdd.spec.HapiSpec.hapiTest; import static com.hedera.services.bdd.spec.keys.ControlForKey.forKey; import static com.hedera.services.bdd.spec.keys.KeyShape.SIMPLE; import static com.hedera.services.bdd.spec.keys.KeyShape.listOf; @@ -39,6 +39,7 @@ import static com.hedera.services.bdd.spec.utilops.UtilVerbs.validateChargedUsd; import static com.hedera.services.bdd.spec.utilops.mod.ModificationUtils.withSuccessivelyVariedBodyIds; import static com.hedera.services.bdd.suites.HapiSuite.asOpArray; +import static com.hedera.services.bdd.suites.HapiSuite.flattened; import static com.hederahashgraph.api.proto.java.ResponseCodeEnum.BUSY; import static com.hederahashgraph.api.proto.java.ResponseCodeEnum.INVALID_CHUNK_NUMBER; import static com.hederahashgraph.api.proto.java.ResponseCodeEnum.INVALID_CHUNK_TRANSACTION_ID; @@ -64,63 +65,52 @@ public class SubmitMessageSuite { @HapiTest final Stream pureCheckFails() { - return defaultHapiSpec("testTopic") - .given(cryptoCreate("nonTopicId")) - .when() - .then( - submitMessageTo(spec -> asTopicId(spec.registry().getAccountID("nonTopicId"))) - .hasPrecheck(INVALID_TOPIC_ID), - submitMessageTo((String) null).hasPrecheck(INVALID_TOPIC_ID)); + return hapiTest( + cryptoCreate("nonTopicId"), + submitMessageTo(spec -> asTopicId(spec.registry().getAccountID("nonTopicId"))) + .hasPrecheck(INVALID_TOPIC_ID), + submitMessageTo((String) null).hasPrecheck(INVALID_TOPIC_ID)); } @HapiTest final Stream idVariantsTreatedAsExpected() { - return defaultHapiSpec("idVariantsTreatedAsExpected") - .given(createTopic("testTopic")) - .when() - .then(submitModified(withSuccessivelyVariedBodyIds(), () -> submitMessageTo("testTopic") - .message("HI"))); + return hapiTest(createTopic("testTopic"), submitModified(withSuccessivelyVariedBodyIds(), () -> submitMessageTo( + "testTopic") + .message("HI"))); } @HapiTest final Stream topicIdIsValidated() { - return defaultHapiSpec("topicIdIsValidated") - .given(cryptoCreate("nonTopicId")) - .when() - .then( - submitMessageTo((String) null) - .hasRetryPrecheckFrom(BUSY) - .hasKnownStatus(INVALID_TOPIC_ID), - submitMessageTo("1.2.3").hasRetryPrecheckFrom(BUSY).hasKnownStatus(INVALID_TOPIC_ID), - submitMessageTo(spec -> asTopicId(spec.registry().getAccountID("nonTopicId"))) - .hasRetryPrecheckFrom(BUSY) - .hasKnownStatus(INVALID_TOPIC_ID)); + return hapiTest( + cryptoCreate("nonTopicId"), + submitMessageTo((String) null).hasRetryPrecheckFrom(BUSY).hasKnownStatus(INVALID_TOPIC_ID), + submitMessageTo("1.2.3").hasRetryPrecheckFrom(BUSY).hasKnownStatus(INVALID_TOPIC_ID), + submitMessageTo(spec -> asTopicId(spec.registry().getAccountID("nonTopicId"))) + .hasRetryPrecheckFrom(BUSY) + .hasKnownStatus(INVALID_TOPIC_ID)); } @HapiTest final Stream messageIsValidated() { - return defaultHapiSpec("messageIsValidated") - .given(createTopic("testTopic")) - .when() - .then( - submitMessageTo("testTopic") - .clearMessage() - .hasRetryPrecheckFrom(BUSY) - .hasPrecheck(INVALID_TOPIC_MESSAGE), - submitMessageTo("testTopic") - .message("") - .hasRetryPrecheckFrom(BUSY) - .hasPrecheck(INVALID_TOPIC_MESSAGE)); + return hapiTest( + createTopic("testTopic"), + submitMessageTo("testTopic") + .clearMessage() + .hasRetryPrecheckFrom(BUSY) + .hasPrecheck(INVALID_TOPIC_MESSAGE), + submitMessageTo("testTopic") + .message("") + .hasRetryPrecheckFrom(BUSY) + .hasPrecheck(INVALID_TOPIC_MESSAGE)); } @HapiTest final Stream messageSubmissionSimple() { - return defaultHapiSpec("messageSubmissionSimple") - .given( - newKeyNamed("submitKey"), - createTopic("testTopic").submitKeyName("submitKey").hasRetryPrecheckFrom(BUSY)) - .when(cryptoCreate("civilian")) - .then(submitMessageTo("testTopic") + return hapiTest( + newKeyNamed("submitKey"), + createTopic("testTopic").submitKeyName("submitKey").hasRetryPrecheckFrom(BUSY), + cryptoCreate("civilian"), + submitMessageTo("testTopic") .message("testmessage") .payingWith("civilian") .hasRetryPrecheckFrom(BUSY) @@ -131,12 +121,11 @@ final Stream messageSubmissionSimple() { final Stream messageSubmissionIncreasesSeqNo() { KeyShape submitKeyShape = threshOf(2, SIMPLE, SIMPLE, listOf(2)); - return defaultHapiSpec("messageSubmissionIncreasesSeqNo") - .given(createTopic("testTopic").submitKeyShape(submitKeyShape)) - .when( - getTopicInfo("testTopic").hasSeqNo(0), - submitMessageTo("testTopic").message("Hello world!").hasRetryPrecheckFrom(BUSY)) - .then(getTopicInfo("testTopic").hasSeqNo(1)); + return hapiTest( + createTopic("testTopic").submitKeyShape(submitKeyShape), + getTopicInfo("testTopic").hasSeqNo(0), + submitMessageTo("testTopic").message("Hello world!").hasRetryPrecheckFrom(BUSY), + getTopicInfo("testTopic").hasSeqNo(1)); } @HapiTest @@ -146,32 +135,30 @@ final Stream messageSubmissionWithSubmitKey() { SigControl validSig = submitKeyShape.signedWith(sigs(ON, OFF, sigs(ON, ON))); SigControl invalidSig = submitKeyShape.signedWith(sigs(ON, OFF, sigs(ON, OFF))); - return defaultHapiSpec("messageSubmissionWithSubmitKey") - .given( - newKeyNamed("submitKey").shape(submitKeyShape), - createTopic("testTopic").submitKeyName("submitKey")) - .when() - .then( - submitMessageTo("testTopic") - .sigControl(forKey("testTopicSubmit", invalidSig)) - .hasRetryPrecheckFrom(BUSY) - .hasKnownStatus(INVALID_SIGNATURE), - submitMessageTo("testTopic") - .sigControl(forKey("testTopicSubmit", validSig)) - .hasRetryPrecheckFrom(BUSY) - .hasKnownStatus(SUCCESS)); + return hapiTest( + newKeyNamed("submitKey").shape(submitKeyShape), + createTopic("testTopic").submitKeyName("submitKey"), + submitMessageTo("testTopic") + .sigControl(forKey("testTopicSubmit", invalidSig)) + .hasRetryPrecheckFrom(BUSY) + .hasKnownStatus(INVALID_SIGNATURE), + submitMessageTo("testTopic") + .sigControl(forKey("testTopicSubmit", validSig)) + .hasRetryPrecheckFrom(BUSY) + .hasKnownStatus(SUCCESS)); } @HapiTest final Stream messageSubmissionMultiple() { final int numMessages = 10; - return defaultHapiSpec("messageSubmissionMultiple") - .given(createTopic("testTopic").hasRetryPrecheckFrom(BUSY)) - .when(inParallel(asOpArray( + return hapiTest( + createTopic("testTopic").hasRetryPrecheckFrom(BUSY), + inParallel(asOpArray( numMessages, - i -> submitMessageTo("testTopic").message("message").hasRetryPrecheckFrom(BUSY)))) - .then(sleepFor(1000), getTopicInfo("testTopic").hasSeqNo(numMessages)); + i -> submitMessageTo("testTopic").message("message").hasRetryPrecheckFrom(BUSY))), + sleepFor(1000), + getTopicInfo("testTopic").hasSeqNo(numMessages)); } @HapiTest @@ -179,12 +166,10 @@ final Stream messageSubmissionOverSize() { final byte[] messageBytes = new byte[4096]; // 4k Arrays.fill(messageBytes, (byte) 0b1); - return defaultHapiSpec("messageSubmissionOverSize") - .given( - newKeyNamed("submitKey"), - createTopic("testTopic").submitKeyName("submitKey").hasRetryPrecheckFrom(BUSY)) - .when() - .then(submitMessageTo("testTopic") + return hapiTest( + newKeyNamed("submitKey"), + createTopic("testTopic").submitKeyName("submitKey").hasRetryPrecheckFrom(BUSY), + submitMessageTo("testTopic") .message(new String(messageBytes)) // In hedera-app we don't enforce such prechecks .hasPrecheckFrom(TRANSACTION_OVERSIZE, BUSY, OK) @@ -195,17 +180,17 @@ final Stream messageSubmissionOverSize() { final Stream feeAsExpected() { final byte[] messageBytes = new byte[100]; // 4k Arrays.fill(messageBytes, (byte) 0b1); - return defaultHapiSpec("feeAsExpected") - .given( - cryptoCreate("payer").hasRetryPrecheckFrom(BUSY), - createTopic("testTopic").submitKeyName("payer").hasRetryPrecheckFrom(BUSY)) - .when(submitMessageTo("testTopic") + return hapiTest( + cryptoCreate("payer").hasRetryPrecheckFrom(BUSY), + createTopic("testTopic").submitKeyName("payer").hasRetryPrecheckFrom(BUSY), + submitMessageTo("testTopic") .blankMemo() .payingWith("payer") .message(new String(messageBytes)) .hasRetryPrecheckFrom(BUSY) - .via("submitMessage")) - .then(sleepFor(1000), validateChargedUsd("submitMessage", 0.0001)); + .via("submitMessage"), + sleepFor(1000), + validateChargedUsd("submitMessage", 0.0001)); } @HapiTest @@ -216,110 +201,100 @@ final Stream messageSubmissionCorrectlyUpdatesRunningHash() { String nonsense = "Nonsense"; String message3 = "Goodbye!"; - return defaultHapiSpec("messageSubmissionCorrectlyUpdatesRunningHash") - .given( - createTopic(topic), - getTopicInfo(topic) - .hasSeqNo(0) - .hasRunningHash(new byte[48]) - .saveRunningHash()) - .when(submitMessageTo(topic) + return hapiTest( + createTopic(topic), + getTopicInfo(topic).hasSeqNo(0).hasRunningHash(new byte[48]).saveRunningHash(), + submitMessageTo(topic) .message(message1) .hasRetryPrecheckFrom(BUSY) - .via("submitMessage1")) - .then( - getTxnRecord("submitMessage1").hasCorrectRunningHash(topic, message1), - submitMessageTo(topic) - .message(message2) - .hasRetryPrecheckFrom(BUSY) - .via("submitMessage2"), - getTxnRecord("submitMessage2").hasCorrectRunningHash(topic, message2), - submitMessageTo(topic) - .message(nonsense) - .via("nonsense") - .chunkInfo(3, 4) - .hasRetryPrecheckFrom(BUSY) - .hasKnownStatus(INVALID_CHUNK_NUMBER), - getTxnRecord("nonsense") - .hasCorrectRunningHash(topic, message2) - .logged(), - submitMessageTo(topic) - .message(message3) - .hasRetryPrecheckFrom(BUSY) - .via("submitMessage3"), - getTxnRecord("submitMessage3").hasCorrectRunningHash(topic, message3)); + .via("submitMessage1"), + getTxnRecord("submitMessage1").hasCorrectRunningHash(topic, message1), + submitMessageTo(topic) + .message(message2) + .hasRetryPrecheckFrom(BUSY) + .via("submitMessage2"), + getTxnRecord("submitMessage2").hasCorrectRunningHash(topic, message2), + submitMessageTo(topic) + .message(nonsense) + .via("nonsense") + .chunkInfo(3, 4) + .hasRetryPrecheckFrom(BUSY) + .hasKnownStatus(INVALID_CHUNK_NUMBER), + getTxnRecord("nonsense").hasCorrectRunningHash(topic, message2).logged(), + submitMessageTo(topic) + .message(message3) + .hasRetryPrecheckFrom(BUSY) + .via("submitMessage3"), + getTxnRecord("submitMessage3").hasCorrectRunningHash(topic, message3)); } @HapiTest final Stream chunkNumberIsValidated() { - return defaultHapiSpec("chunkNumberIsValidated") - .given(createTopic("testTopic")) - .when() - .then( - submitMessageTo("testTopic") - .message("failsForChunkNumberGreaterThanTotalChunks") - .chunkInfo(2, 3) - .hasRetryPrecheckFrom(BUSY) - .hasKnownStatus(INVALID_CHUNK_NUMBER), - submitMessageTo("testTopic") - .message("acceptsChunkNumberLessThanTotalChunks") - .chunkInfo(3, 2) - .hasRetryPrecheckFrom(BUSY) - .hasKnownStatus(SUCCESS), - submitMessageTo("testTopic") - .message("acceptsChunkNumberEqualTotalChunks") - .chunkInfo(5, 5) - .hasRetryPrecheckFrom(BUSY) - .hasKnownStatus(SUCCESS)); + return hapiTest( + createTopic("testTopic"), + submitMessageTo("testTopic") + .message("failsForChunkNumberGreaterThanTotalChunks") + .chunkInfo(2, 3) + .hasRetryPrecheckFrom(BUSY) + .hasKnownStatus(INVALID_CHUNK_NUMBER), + submitMessageTo("testTopic") + .message("acceptsChunkNumberLessThanTotalChunks") + .chunkInfo(3, 2) + .hasRetryPrecheckFrom(BUSY) + .hasKnownStatus(SUCCESS), + submitMessageTo("testTopic") + .message("acceptsChunkNumberEqualTotalChunks") + .chunkInfo(5, 5) + .hasRetryPrecheckFrom(BUSY) + .hasKnownStatus(SUCCESS)); } @HapiTest final Stream chunkTransactionIDIsValidated() { - return defaultHapiSpec("chunkTransactionIDIsValidated") - .given(cryptoCreate("initialTransactionPayer"), createTopic("testTopic")) - .when() - .then( - submitMessageTo("testTopic") - .message("failsForDifferentPayers") - .chunkInfo(3, 2, "initialTransactionPayer") - .hasRetryPrecheckFrom(BUSY) - .hasKnownStatus(INVALID_CHUNK_TRANSACTION_ID), - // Add delay to make sure the valid start of the transaction will - // not match - // that of the initialTransactionID - sleepFor(1000), - /* AcceptsChunkNumberDifferentThan1HavingTheSamePayerEvenWhenNotMatchingValidStart */ - submitMessageTo("testTopic") - .message("A") - .chunkInfo(3, 3, "initialTransactionPayer") - .payingWith("initialTransactionPayer") - .hasRetryPrecheckFrom(BUSY) - .hasKnownStatus(SUCCESS), - /* FailsForTransactionIDOfChunkNumber1NotMatchingTheEntireInitialTransactionID */ - sleepFor(1000), - submitMessageTo("testTopic") - .message("B") - .chunkInfo(2, 1) - // Also add delay here - .hasRetryPrecheckFrom(BUSY) - .hasKnownStatus(INVALID_CHUNK_TRANSACTION_ID), - /* AcceptsChunkNumber1WhenItsTransactionIDMatchesTheEntireInitialTransactionID */ - submitMessageTo("testTopic") - .message("C") - .chunkInfo(4, 1) - .via("firstChunk") - .payingWith("initialTransactionPayer") - .usePresetTimestamp() - .hasRetryPrecheckFrom(BUSY) - .hasKnownStatus(SUCCESS)); + return hapiTest( + cryptoCreate("initialTransactionPayer"), + createTopic("testTopic"), + submitMessageTo("testTopic") + .message("failsForDifferentPayers") + .chunkInfo(3, 2, "initialTransactionPayer") + .hasRetryPrecheckFrom(BUSY) + .hasKnownStatus(INVALID_CHUNK_TRANSACTION_ID), + // Add delay to make sure the valid start of the transaction will + // not match + // that of the initialTransactionID + sleepFor(1000), + /* AcceptsChunkNumberDifferentThan1HavingTheSamePayerEvenWhenNotMatchingValidStart */ + submitMessageTo("testTopic") + .message("A") + .chunkInfo(3, 3, "initialTransactionPayer") + .payingWith("initialTransactionPayer") + .hasRetryPrecheckFrom(BUSY) + .hasKnownStatus(SUCCESS), + /* FailsForTransactionIDOfChunkNumber1NotMatchingTheEntireInitialTransactionID */ + sleepFor(1000), + submitMessageTo("testTopic") + .message("B") + .chunkInfo(2, 1) + // Also add delay here + .hasRetryPrecheckFrom(BUSY) + .hasKnownStatus(INVALID_CHUNK_TRANSACTION_ID), + /* AcceptsChunkNumber1WhenItsTransactionIDMatchesTheEntireInitialTransactionID */ + submitMessageTo("testTopic") + .message("C") + .chunkInfo(4, 1) + .via("firstChunk") + .payingWith("initialTransactionPayer") + .usePresetTimestamp() + .hasRetryPrecheckFrom(BUSY) + .hasKnownStatus(SUCCESS)); } @HapiTest final Stream longMessageIsFragmentedIntoChunks() { String fileForLongMessage = "src/main/resources/RandomLargeBinary.bin"; - return defaultHapiSpec("longMessageIsFragmentedIntoChunks") - .given(cryptoCreate("payer"), createTopic("testTopic")) - .when() - .then(chunkAFile(fileForLongMessage, CHUNK_SIZE, "payer", "testTopic")); + return hapiTest(flattened( + cryptoCreate("payer"), + createTopic("testTopic"), + chunkAFile(fileForLongMessage, CHUNK_SIZE, "payer", "testTopic"))); } } diff --git a/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/consensus/TopicCreateSuite.java b/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/consensus/TopicCreateSuite.java index 5e37f2253052..161a03a61d23 100644 --- a/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/consensus/TopicCreateSuite.java +++ b/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/consensus/TopicCreateSuite.java @@ -16,7 +16,6 @@ package com.hedera.services.bdd.suites.consensus; -import static com.hedera.services.bdd.spec.HapiSpec.defaultHapiSpec; import static com.hedera.services.bdd.spec.HapiSpec.hapiTest; import static com.hedera.services.bdd.spec.queries.QueryVerbs.getTopicInfo; import static com.hedera.services.bdd.spec.queries.QueryVerbs.getTxnRecord; @@ -61,44 +60,35 @@ public class TopicCreateSuite { @HapiTest final Stream adminKeyIsValidated() { - return defaultHapiSpec("AdminKeyIsValidated") - .given() - .when() - .then(createTopic("testTopic") - .adminKeyName(NONSENSE_KEY) - .signedBy(GENESIS) - .hasPrecheckFrom(OK, BAD_ENCODING) - .hasKnownStatus(BAD_ENCODING)); + return hapiTest(createTopic("testTopic") + .adminKeyName(NONSENSE_KEY) + .signedBy(GENESIS) + .hasPrecheckFrom(OK, BAD_ENCODING) + .hasKnownStatus(BAD_ENCODING)); } @HapiTest final Stream submitKeyIsValidated() { - return defaultHapiSpec("SubmitKeyIsValidated") - .given() - .when() - .then(createTopic("testTopic") - .submitKeyName(NONSENSE_KEY) - .signedBy(GENESIS) - .hasKnownStatus(BAD_ENCODING)); + return hapiTest(createTopic("testTopic") + .submitKeyName(NONSENSE_KEY) + .signedBy(GENESIS) + .hasKnownStatus(BAD_ENCODING)); } @HapiTest final Stream autoRenewAccountIsValidated() { - return defaultHapiSpec("AutoRenewAccountIsValidated") - .given() - .when() - .then(createTopic("testTopic") - .autoRenewAccountId("1.2.3") - .signedBy(GENESIS) - .hasKnownStatus(INVALID_AUTORENEW_ACCOUNT)); + return hapiTest(createTopic("testTopic") + .autoRenewAccountId("1.2.3") + .signedBy(GENESIS) + .hasKnownStatus(INVALID_AUTORENEW_ACCOUNT)); } @HapiTest final Stream autoRenewAccountIdNeedsAdminKeyToo() { - return defaultHapiSpec("autoRenewAccountIdNeedsAdminKeyToo") - .given(cryptoCreate("payer"), cryptoCreate("autoRenewAccount")) - .when() - .then(createTopic("noAdminKeyExplicitAutoRenewAccount") + return hapiTest( + cryptoCreate("payer"), + cryptoCreate("autoRenewAccount"), + createTopic("noAdminKeyExplicitAutoRenewAccount") .payingWith("payer") .autoRenewAccountId("autoRenewAccount") .signedBy("payer", "autoRenewAccount") @@ -109,10 +99,10 @@ final Stream autoRenewAccountIdNeedsAdminKeyToo() { @HapiTest final Stream idVariantsTreatedAsExpected() { final var autoRenewAccount = "autoRenewAccount"; - return defaultHapiSpec("idVariantsTreatedAsExpected") - .given(cryptoCreate(autoRenewAccount), newKeyNamed("adminKey")) - .when() - .then(submitModified( + return hapiTest( + cryptoCreate(autoRenewAccount), + newKeyNamed("adminKey"), + submitModified( withSuccessivelyVariedBodyIds(), () -> createTopic("topic").adminKeyName("adminKey").autoRenewAccountId(autoRenewAccount))); } @@ -121,27 +111,21 @@ final Stream idVariantsTreatedAsExpected() { final Stream autoRenewPeriodIsValidated() { final var tooShortAutoRenewPeriod = "tooShortAutoRenewPeriod"; final var tooLongAutoRenewPeriod = "tooLongAutoRenewPeriod"; - return defaultHapiSpec("autoRenewPeriodIsValidated") - .given() - .when() - .then( - createTopic(tooShortAutoRenewPeriod) - .autoRenewPeriod(0L) - .hasKnownStatus(AUTORENEW_DURATION_NOT_IN_RANGE), - createTopic(tooLongAutoRenewPeriod) - .autoRenewPeriod(Long.MAX_VALUE) - .hasKnownStatus(AUTORENEW_DURATION_NOT_IN_RANGE)); + return hapiTest( + createTopic(tooShortAutoRenewPeriod) + .autoRenewPeriod(0L) + .hasKnownStatus(AUTORENEW_DURATION_NOT_IN_RANGE), + createTopic(tooLongAutoRenewPeriod) + .autoRenewPeriod(Long.MAX_VALUE) + .hasKnownStatus(AUTORENEW_DURATION_NOT_IN_RANGE)); } @HapiTest final Stream noAutoRenewPeriod() { - return defaultHapiSpec("noAutoRenewPeriod") - .given() - .when() - .then(createTopic("testTopic") - .clearAutoRenewPeriod() - // No obvious reason to require INVALID_RENEWAL_PERIOD here - .hasKnownStatusFrom(INVALID_RENEWAL_PERIOD, AUTORENEW_DURATION_NOT_IN_RANGE)); + return hapiTest(createTopic("testTopic") + .clearAutoRenewPeriod() + // No obvious reason to require INVALID_RENEWAL_PERIOD here + .hasKnownStatusFrom(INVALID_RENEWAL_PERIOD, AUTORENEW_DURATION_NOT_IN_RANGE)); } @HapiTest @@ -149,78 +133,71 @@ final Stream signingRequirementsEnforced() { long PAYER_BALANCE = 1_999_999_999L; final var contractWithAdminKey = "nonCryptoAccount"; - return defaultHapiSpec("SigningRequirementsEnforced") - .given( - newKeyNamed("adminKey"), - newKeyNamed("contractAdminKey"), - newKeyNamed("submitKey"), - newKeyNamed("wrongKey"), - cryptoCreate("payer").balance(PAYER_BALANCE), - cryptoCreate("autoRenewAccount"), - // This will have an admin key - createDefaultContract(contractWithAdminKey).adminKey("contractAdminKey"), - uploadInitCode(PAY_RECEIVABLE_CONTRACT), - // And this won't - contractCreate(PAY_RECEIVABLE_CONTRACT).omitAdminKey()) - .when( - createTopic("testTopic") - .payingWith("payer") - .signedBy("wrongKey") - .hasPrecheck(INVALID_SIGNATURE), - // But contracts without admin keys will get INVALID_SIGNATURE (can't sign!) - createTopic("NotToBe") - .autoRenewAccountId(PAY_RECEIVABLE_CONTRACT) - .hasKnownStatusFrom(INVALID_SIGNATURE), - createTopic("testTopic") - .payingWith("payer") - .autoRenewAccountId("autoRenewAccount") - /* SigMap missing signature from auto-renew account's key. */ - .signedBy("payer") - .hasKnownStatus(INVALID_SIGNATURE), - createTopic("testTopic") - .payingWith("payer") - .adminKeyName("adminKey") - /* SigMap missing signature from adminKey. */ - .signedBy("payer") - .hasKnownStatus(INVALID_SIGNATURE), - createTopic("testTopic") - .payingWith("payer") - .adminKeyName("adminKey") - .autoRenewAccountId("autoRenewAccount") - /* SigMap missing signature from auto-renew account's key. */ - .signedBy("payer", "adminKey") - .hasKnownStatus(INVALID_SIGNATURE), - createTopic("testTopic") - .payingWith("payer") - .adminKeyName("adminKey") - .autoRenewAccountId("autoRenewAccount") - /* SigMap missing signature from adminKey. */ - .signedBy("payer", "autoRenewAccount") - .hasKnownStatus(INVALID_SIGNATURE), - // In hedera-app, we'll allow contracts with admin keys to be auto-renew accounts - createTopic("withContractAutoRenew") - .adminKeyName("adminKey") - .autoRenewAccountId(contractWithAdminKey)) - .then( - createTopic("noAdminKeyNoAutoRenewAccount"), - getTopicInfo("noAdminKeyNoAutoRenewAccount") - .hasNoAdminKey() - .logged(), - createTopic("explicitAdminKeyNoAutoRenewAccount").adminKeyName("adminKey"), - getTopicInfo("explicitAdminKeyNoAutoRenewAccount") - .hasAdminKey("adminKey") - .logged(), - createTopic("explicitAdminKeyExplicitAutoRenewAccount") - .adminKeyName("adminKey") - .autoRenewAccountId("autoRenewAccount"), - getTopicInfo("explicitAdminKeyExplicitAutoRenewAccount") - .hasAdminKey("adminKey") - .hasAutoRenewAccount("autoRenewAccount") - .logged(), - getTopicInfo("withContractAutoRenew") - .hasAdminKey("adminKey") - .hasAutoRenewAccount(contractWithAdminKey) - .logged()); + return hapiTest( + newKeyNamed("adminKey"), + newKeyNamed("contractAdminKey"), + newKeyNamed("submitKey"), + newKeyNamed("wrongKey"), + cryptoCreate("payer").balance(PAYER_BALANCE), + cryptoCreate("autoRenewAccount"), + // This will have an admin key + createDefaultContract(contractWithAdminKey).adminKey("contractAdminKey"), + uploadInitCode(PAY_RECEIVABLE_CONTRACT), + // And this won't + contractCreate(PAY_RECEIVABLE_CONTRACT).omitAdminKey(), + createTopic("testTopic") + .payingWith("payer") + .signedBy("wrongKey") + .hasPrecheck(INVALID_SIGNATURE), + // But contracts without admin keys will get INVALID_SIGNATURE (can't sign!) + createTopic("NotToBe") + .autoRenewAccountId(PAY_RECEIVABLE_CONTRACT) + .hasKnownStatusFrom(INVALID_SIGNATURE), + createTopic("testTopic") + .payingWith("payer") + .autoRenewAccountId("autoRenewAccount") + /* SigMap missing signature from auto-renew account's key. */ + .signedBy("payer") + .hasKnownStatus(INVALID_SIGNATURE), + createTopic("testTopic") + .payingWith("payer") + .adminKeyName("adminKey") + /* SigMap missing signature from adminKey. */ + .signedBy("payer") + .hasKnownStatus(INVALID_SIGNATURE), + createTopic("testTopic") + .payingWith("payer") + .adminKeyName("adminKey") + .autoRenewAccountId("autoRenewAccount") + /* SigMap missing signature from auto-renew account's key. */ + .signedBy("payer", "adminKey") + .hasKnownStatus(INVALID_SIGNATURE), + createTopic("testTopic") + .payingWith("payer") + .adminKeyName("adminKey") + .autoRenewAccountId("autoRenewAccount") + /* SigMap missing signature from adminKey. */ + .signedBy("payer", "autoRenewAccount") + .hasKnownStatus(INVALID_SIGNATURE), + // In hedera-app, we'll allow contracts with admin keys to be auto-renew accounts + createTopic("withContractAutoRenew").adminKeyName("adminKey").autoRenewAccountId(contractWithAdminKey), + createTopic("noAdminKeyNoAutoRenewAccount"), + getTopicInfo("noAdminKeyNoAutoRenewAccount").hasNoAdminKey().logged(), + createTopic("explicitAdminKeyNoAutoRenewAccount").adminKeyName("adminKey"), + getTopicInfo("explicitAdminKeyNoAutoRenewAccount") + .hasAdminKey("adminKey") + .logged(), + createTopic("explicitAdminKeyExplicitAutoRenewAccount") + .adminKeyName("adminKey") + .autoRenewAccountId("autoRenewAccount"), + getTopicInfo("explicitAdminKeyExplicitAutoRenewAccount") + .hasAdminKey("adminKey") + .hasAutoRenewAccount("autoRenewAccount") + .logged(), + getTopicInfo("withContractAutoRenew") + .hasAdminKey("adminKey") + .hasAutoRenewAccount(contractWithAdminKey) + .logged()); } @HapiTest @@ -238,88 +215,78 @@ final Stream allFieldsSetHappyCase() { @HapiTest final Stream feeAsExpected() { - return defaultHapiSpec("feeAsExpected") - .given( - newKeyNamed("adminKey"), - newKeyNamed("submitKey"), - cryptoCreate("autoRenewAccount"), - cryptoCreate("payer").balance(ONE_HUNDRED_HBARS)) - .when(createTopic("testTopic") + return hapiTest( + newKeyNamed("adminKey"), + newKeyNamed("submitKey"), + cryptoCreate("autoRenewAccount"), + cryptoCreate("payer").balance(ONE_HUNDRED_HBARS), + createTopic("testTopic") .topicMemo("testmemo") .adminKeyName("adminKey") .submitKeyName("submitKey") .autoRenewAccountId("autoRenewAccount") .payingWith("payer") - .via("topicCreate")) - .then(validateChargedUsd("topicCreate", 0.0226)); + .via("topicCreate"), + validateChargedUsd("topicCreate", 0.0226)); } @HapiTest final Stream getInfoIdVariantsTreatedAsExpected() { - return defaultHapiSpec("idVariantsTreatedAsExpected") - .given(createTopic("topic")) - .when() - .then(sendModified(withSuccessivelyVariedQueryIds(), () -> getTopicInfo("topic"))); + return hapiTest( + createTopic("topic"), sendModified(withSuccessivelyVariedQueryIds(), () -> getTopicInfo("topic"))); } @HapiTest final Stream getInfoAllFieldsSetHappyCase() { // sequenceNumber should be 0 and runningHash should be 48 bytes all 0s. final AtomicReference targetLedgerId = new AtomicReference<>(); - return defaultHapiSpec("AllFieldsSetHappyCase") - .given( - newKeyNamed("adminKey"), - newKeyNamed("submitKey"), - cryptoCreate("autoRenewAccount"), - cryptoCreate("payer"), - createTopic(TEST_TOPIC) - .topicMemo(TESTMEMO) - .adminKeyName("adminKey") - .submitKeyName("submitKey") - .autoRenewAccountId("autoRenewAccount") - .via("createTopic")) - .when() - .then( - exposeTargetLedgerIdTo(targetLedgerId::set), - sourcing(() -> getTopicInfo(TEST_TOPIC) - .hasEncodedLedgerId(targetLedgerId.get()) - .hasMemo(TESTMEMO) - .hasAdminKey("adminKey") - .hasSubmitKey("submitKey") - .hasAutoRenewAccount("autoRenewAccount") - .hasSeqNo(0) - .hasRunningHash(new byte[48])), - getTxnRecord("createTopic").logged(), - submitMessageTo(TEST_TOPIC) - .blankMemo() - .payingWith("payer") - .message(new String("test".getBytes())) - .via("submitMessage"), - getTxnRecord("submitMessage").logged(), - sourcing(() -> getTopicInfo(TEST_TOPIC) - .hasEncodedLedgerId(targetLedgerId.get()) - .hasMemo(TESTMEMO) - .hasAdminKey("adminKey") - .hasSubmitKey("submitKey") - .hasAutoRenewAccount("autoRenewAccount") - .hasSeqNo(1) - .logged()), - updateTopic(TEST_TOPIC) - .topicMemo("Don't worry about the vase") - .via("updateTopic"), - getTxnRecord("updateTopic").logged(), - sourcing(() -> getTopicInfo(TEST_TOPIC) - .hasEncodedLedgerId(targetLedgerId.get()) - .hasMemo("Don't worry about the vase") - .hasAdminKey("adminKey") - .hasSubmitKey("submitKey") - .hasAutoRenewAccount("autoRenewAccount") - .hasSeqNo(1) - .logged()), - deleteTopic(TEST_TOPIC).via("deleteTopic"), - getTxnRecord("deleteTopic").logged(), - getTopicInfo(TEST_TOPIC) - .hasCostAnswerPrecheck(INVALID_TOPIC_ID) - .logged()); + return hapiTest( + newKeyNamed("adminKey"), + newKeyNamed("submitKey"), + cryptoCreate("autoRenewAccount"), + cryptoCreate("payer"), + createTopic(TEST_TOPIC) + .topicMemo(TESTMEMO) + .adminKeyName("adminKey") + .submitKeyName("submitKey") + .autoRenewAccountId("autoRenewAccount") + .via("createTopic"), + exposeTargetLedgerIdTo(targetLedgerId::set), + sourcing(() -> getTopicInfo(TEST_TOPIC) + .hasEncodedLedgerId(targetLedgerId.get()) + .hasMemo(TESTMEMO) + .hasAdminKey("adminKey") + .hasSubmitKey("submitKey") + .hasAutoRenewAccount("autoRenewAccount") + .hasSeqNo(0) + .hasRunningHash(new byte[48])), + getTxnRecord("createTopic").logged(), + submitMessageTo(TEST_TOPIC) + .blankMemo() + .payingWith("payer") + .message(new String("test".getBytes())) + .via("submitMessage"), + getTxnRecord("submitMessage").logged(), + sourcing(() -> getTopicInfo(TEST_TOPIC) + .hasEncodedLedgerId(targetLedgerId.get()) + .hasMemo(TESTMEMO) + .hasAdminKey("adminKey") + .hasSubmitKey("submitKey") + .hasAutoRenewAccount("autoRenewAccount") + .hasSeqNo(1) + .logged()), + updateTopic(TEST_TOPIC).topicMemo("Don't worry about the vase").via("updateTopic"), + getTxnRecord("updateTopic").logged(), + sourcing(() -> getTopicInfo(TEST_TOPIC) + .hasEncodedLedgerId(targetLedgerId.get()) + .hasMemo("Don't worry about the vase") + .hasAdminKey("adminKey") + .hasSubmitKey("submitKey") + .hasAutoRenewAccount("autoRenewAccount") + .hasSeqNo(1) + .logged()), + deleteTopic(TEST_TOPIC).via("deleteTopic"), + getTxnRecord("deleteTopic").logged(), + getTopicInfo(TEST_TOPIC).hasCostAnswerPrecheck(INVALID_TOPIC_ID).logged()); } } diff --git a/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/consensus/TopicDeleteSuite.java b/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/consensus/TopicDeleteSuite.java index 791a39790943..3fb285333798 100644 --- a/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/consensus/TopicDeleteSuite.java +++ b/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/consensus/TopicDeleteSuite.java @@ -16,7 +16,6 @@ package com.hedera.services.bdd.suites.consensus; -import static com.hedera.services.bdd.spec.HapiSpec.defaultHapiSpec; import static com.hedera.services.bdd.spec.HapiSpec.hapiTest; import static com.hedera.services.bdd.spec.queries.QueryVerbs.getTopicInfo; import static com.hedera.services.bdd.spec.transactions.TxnUtils.asTopicId; @@ -38,29 +37,26 @@ public class TopicDeleteSuite { @HapiTest final Stream idVariantsTreatedAsExpected() { - return defaultHapiSpec("idVariantsTreatedAsExpected") - .given(newKeyNamed("adminKey")) - .when(createTopic("topic").adminKeyName("adminKey")) - .then(submitModified(withSuccessivelyVariedBodyIds(), () -> deleteTopic("topic"))); + return hapiTest( + newKeyNamed("adminKey"), + createTopic("topic").adminKeyName("adminKey"), + submitModified(withSuccessivelyVariedBodyIds(), () -> deleteTopic("topic"))); } @HapiTest final Stream pureCheckFails() { - return defaultHapiSpec("CannotDeleteAccountAsTopic") - .given(cryptoCreate("nonTopicId")) - .when() - .then( - deleteTopic(spec -> asTopicId(spec.registry().getAccountID("nonTopicId"))) - .hasPrecheck(INVALID_TOPIC_ID), - deleteTopic((String) null).hasPrecheck(INVALID_TOPIC_ID)); + return hapiTest( + cryptoCreate("nonTopicId"), + deleteTopic(spec -> asTopicId(spec.registry().getAccountID("nonTopicId"))) + .hasPrecheck(INVALID_TOPIC_ID), + deleteTopic((String) null).hasPrecheck(INVALID_TOPIC_ID)); } @HapiTest final Stream cannotDeleteAccountAsTopic() { - return defaultHapiSpec("CannotDeleteAccountAsTopic") - .given(cryptoCreate("nonTopicId")) - .when() - .then(deleteTopic(spec -> asTopicId(spec.registry().getAccountID("nonTopicId"))) + return hapiTest( + cryptoCreate("nonTopicId"), + deleteTopic(spec -> asTopicId(spec.registry().getAccountID("nonTopicId"))) .hasKnownStatus(INVALID_TOPIC_ID)); } @@ -74,41 +70,38 @@ final Stream topicIdIsValidated() { @HapiTest final Stream noAdminKeyCannotDelete() { - return defaultHapiSpec("noAdminKeyCannotDelete") - .given(createTopic("testTopic")) - .when(deleteTopic("testTopic").hasKnownStatus(UNAUTHORIZED)) - .then(); + return hapiTest(createTopic("testTopic"), deleteTopic("testTopic").hasKnownStatus(UNAUTHORIZED)); } @HapiTest final Stream deleteWithAdminKey() { - return defaultHapiSpec("deleteWithAdminKey") - .given(newKeyNamed("adminKey"), createTopic("testTopic").adminKeyName("adminKey")) - .when(deleteTopic("testTopic").hasPrecheck(ResponseCodeEnum.OK)) - .then(getTopicInfo("testTopic").hasCostAnswerPrecheck(INVALID_TOPIC_ID)); + return hapiTest( + newKeyNamed("adminKey"), + createTopic("testTopic").adminKeyName("adminKey"), + deleteTopic("testTopic").hasPrecheck(ResponseCodeEnum.OK), + getTopicInfo("testTopic").hasCostAnswerPrecheck(INVALID_TOPIC_ID)); } @HapiTest final Stream deleteFailedWithWrongKey() { long PAYER_BALANCE = 1_999_999_999L; - return defaultHapiSpec("deleteFailedWithWrongKey") - .given( - newKeyNamed("adminKey"), - newKeyNamed("wrongKey"), - cryptoCreate("payer").balance(PAYER_BALANCE), - createTopic("testTopic").adminKeyName("adminKey")) - .when(deleteTopic("testTopic") + return hapiTest( + newKeyNamed("adminKey"), + newKeyNamed("wrongKey"), + cryptoCreate("payer").balance(PAYER_BALANCE), + createTopic("testTopic").adminKeyName("adminKey"), + deleteTopic("testTopic") .payingWith("payer") .signedBy("payer", "wrongKey") - .hasKnownStatus(ResponseCodeEnum.INVALID_SIGNATURE)) - .then(); + .hasKnownStatus(ResponseCodeEnum.INVALID_SIGNATURE)); } @HapiTest final Stream feeAsExpected() { - return defaultHapiSpec("feeAsExpected") - .given(cryptoCreate("payer"), createTopic("testTopic").adminKeyName("payer")) - .when(deleteTopic("testTopic").blankMemo().payingWith("payer").via("topicDelete")) - .then(validateChargedUsd("topicDelete", 0.005)); + return hapiTest( + cryptoCreate("payer"), + createTopic("testTopic").adminKeyName("payer"), + deleteTopic("testTopic").blankMemo().payingWith("payer").via("topicDelete"), + validateChargedUsd("topicDelete", 0.005)); } } diff --git a/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/consensus/TopicUpdateSuite.java b/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/consensus/TopicUpdateSuite.java index cb2d0e19403b..1392d8a8a25a 100644 --- a/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/consensus/TopicUpdateSuite.java +++ b/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/consensus/TopicUpdateSuite.java @@ -16,7 +16,6 @@ package com.hedera.services.bdd.suites.consensus; -import static com.hedera.services.bdd.spec.HapiSpec.defaultHapiSpec; import static com.hedera.services.bdd.spec.HapiSpec.hapiTest; import static com.hedera.services.bdd.spec.queries.QueryVerbs.getTopicInfo; import static com.hedera.services.bdd.spec.transactions.TxnVerbs.createTopic; @@ -60,27 +59,23 @@ public class TopicUpdateSuite { @HapiTest final Stream pureCheckFails() { - return defaultHapiSpec("testTopic") - .given() - .when() - .then(updateTopic("0.0.1").hasPrecheck(INVALID_TOPIC_ID)); + return hapiTest(updateTopic("0.0.1").hasPrecheck(INVALID_TOPIC_ID)); } @HapiTest final Stream updateToMissingTopicFails() { - return defaultHapiSpec("updateToMissingTopicFails") - .given() - .when() - .then(updateTopic("1.2.3").hasKnownStatus(INVALID_TOPIC_ID)); + return hapiTest(updateTopic("1.2.3").hasKnownStatus(INVALID_TOPIC_ID)); } @HapiTest final Stream idVariantsTreatedAsExpected() { final var autoRenewAccount = "autoRenewAccount"; - return defaultHapiSpec("idVariantsTreatedAsExpected") - .given(cryptoCreate(autoRenewAccount), cryptoCreate("replacementAccount"), newKeyNamed("adminKey")) - .when(createTopic("topic").adminKeyName("adminKey").autoRenewAccountId(autoRenewAccount)) - .then(submitModified(withSuccessivelyVariedBodyIds(), () -> updateTopic("topic") + return hapiTest( + cryptoCreate(autoRenewAccount), + cryptoCreate("replacementAccount"), + newKeyNamed("adminKey"), + createTopic("topic").adminKeyName("adminKey").autoRenewAccountId(autoRenewAccount), + submitModified(withSuccessivelyVariedBodyIds(), () -> updateTopic("topic") .autoRenewAccountId("replacementAccount"))); } @@ -89,21 +84,20 @@ final Stream validateMultipleFields() { byte[] longBytes = new byte[1000]; Arrays.fill(longBytes, (byte) 33); String longMemo = new String(longBytes, StandardCharsets.UTF_8); - return defaultHapiSpec("validateMultipleFields") - .given(newKeyNamed("adminKey"), createTopic("testTopic").adminKeyName("adminKey")) - .when() - .then( - updateTopic("testTopic") - .adminKey(NONSENSE_KEY) - .hasPrecheckFrom(BAD_ENCODING, OK) - .hasKnownStatus(BAD_ENCODING), - updateTopic("testTopic").submitKey(NONSENSE_KEY).hasKnownStatus(BAD_ENCODING), - updateTopic("testTopic").topicMemo(longMemo).hasKnownStatus(MEMO_TOO_LONG), - updateTopic("testTopic").topicMemo(ZERO_BYTE_MEMO).hasKnownStatus(INVALID_ZERO_BYTE_IN_STRING), - updateTopic("testTopic").autoRenewPeriod(0).hasKnownStatus(AUTORENEW_DURATION_NOT_IN_RANGE), - updateTopic("testTopic") - .autoRenewPeriod(Long.MAX_VALUE) - .hasKnownStatus(AUTORENEW_DURATION_NOT_IN_RANGE)); + return hapiTest( + newKeyNamed("adminKey"), + createTopic("testTopic").adminKeyName("adminKey"), + updateTopic("testTopic") + .adminKey(NONSENSE_KEY) + .hasPrecheckFrom(BAD_ENCODING, OK) + .hasKnownStatus(BAD_ENCODING), + updateTopic("testTopic").submitKey(NONSENSE_KEY).hasKnownStatus(BAD_ENCODING), + updateTopic("testTopic").topicMemo(longMemo).hasKnownStatus(MEMO_TOO_LONG), + updateTopic("testTopic").topicMemo(ZERO_BYTE_MEMO).hasKnownStatus(INVALID_ZERO_BYTE_IN_STRING), + updateTopic("testTopic").autoRenewPeriod(0).hasKnownStatus(AUTORENEW_DURATION_NOT_IN_RANGE), + updateTopic("testTopic") + .autoRenewPeriod(Long.MAX_VALUE) + .hasKnownStatus(AUTORENEW_DURATION_NOT_IN_RANGE)); } @HapiTest @@ -115,31 +109,27 @@ final Stream topicUpdateSigReqsEnforcedAtConsensus() { .autoRenewAccountId("newAutoRenewAccount") .signedBy(signers); - return defaultHapiSpec("topicUpdateSigReqsEnforcedAtConsensus") - .given( - newKeyNamed("oldAdminKey"), - cryptoCreate("oldAutoRenewAccount"), - newKeyNamed("newAdminKey"), - cryptoCreate("newAutoRenewAccount"), - cryptoCreate("payer").balance(PAYER_BALANCE), - createTopic("testTopic").adminKeyName("oldAdminKey").autoRenewAccountId("oldAutoRenewAccount")) - .when( - updateTopicSignedBy - .apply(new String[] {"payer", "oldAdminKey"}) - .hasKnownStatus(INVALID_SIGNATURE), - updateTopicSignedBy - .apply(new String[] {"payer", "oldAdminKey", "newAdminKey"}) - .hasKnownStatus(INVALID_SIGNATURE), - updateTopicSignedBy - .apply(new String[] {"payer", "oldAdminKey", "newAutoRenewAccount"}) - .hasKnownStatus(INVALID_SIGNATURE), - updateTopicSignedBy - .apply(new String[] {"payer", "newAdminKey", "newAutoRenewAccount"}) - .hasKnownStatus(INVALID_SIGNATURE), - updateTopicSignedBy - .apply(new String[] {"payer", "oldAdminKey", "newAdminKey", "newAutoRenewAccount"}) - .hasKnownStatus(SUCCESS)) - .then(getTopicInfo("testTopic") + return hapiTest( + newKeyNamed("oldAdminKey"), + cryptoCreate("oldAutoRenewAccount"), + newKeyNamed("newAdminKey"), + cryptoCreate("newAutoRenewAccount"), + cryptoCreate("payer").balance(PAYER_BALANCE), + createTopic("testTopic").adminKeyName("oldAdminKey").autoRenewAccountId("oldAutoRenewAccount"), + updateTopicSignedBy.apply(new String[] {"payer", "oldAdminKey"}).hasKnownStatus(INVALID_SIGNATURE), + updateTopicSignedBy + .apply(new String[] {"payer", "oldAdminKey", "newAdminKey"}) + .hasKnownStatus(INVALID_SIGNATURE), + updateTopicSignedBy + .apply(new String[] {"payer", "oldAdminKey", "newAutoRenewAccount"}) + .hasKnownStatus(INVALID_SIGNATURE), + updateTopicSignedBy + .apply(new String[] {"payer", "newAdminKey", "newAutoRenewAccount"}) + .hasKnownStatus(INVALID_SIGNATURE), + updateTopicSignedBy + .apply(new String[] {"payer", "oldAdminKey", "newAdminKey", "newAutoRenewAccount"}) + .hasKnownStatus(SUCCESS), + getTopicInfo("testTopic") .logged() .hasAdminKey("newAdminKey") .hasAutoRenewAccount("newAutoRenewAccount")); @@ -147,13 +137,12 @@ final Stream topicUpdateSigReqsEnforcedAtConsensus() { @HapiTest final Stream updateSubmitKeyToDiffKey() { - return defaultHapiSpec("updateSubmitKeyToDiffKey") - .given( - newKeyNamed("adminKey"), - newKeyNamed("submitKey"), - createTopic("testTopic").adminKeyName("adminKey")) - .when(updateTopic("testTopic").submitKey("submitKey")) - .then(getTopicInfo("testTopic") + return hapiTest( + newKeyNamed("adminKey"), + newKeyNamed("submitKey"), + createTopic("testTopic").adminKeyName("adminKey"), + updateTopic("testTopic").submitKey("submitKey"), + getTopicInfo("testTopic") .hasSubmitKey("submitKey") .hasAdminKey("adminKey") .logged()); @@ -161,64 +150,60 @@ final Stream updateSubmitKeyToDiffKey() { @HapiTest final Stream canRemoveSubmitKeyDuringUpdate() { - return defaultHapiSpec("updateSubmitKeyToDiffKey") - .given( - newKeyNamed("adminKey"), - newKeyNamed("submitKey"), - createTopic("testTopic").adminKeyName("adminKey").submitKeyName("submitKey")) - .when( - submitMessageTo("testTopic").message("message"), - updateTopic("testTopic").submitKey(EMPTY_KEY)) - .then( - getTopicInfo("testTopic").hasNoSubmitKey().hasAdminKey("adminKey"), - submitMessageTo("testTopic").message("message").logged()); + return hapiTest( + newKeyNamed("adminKey"), + newKeyNamed("submitKey"), + createTopic("testTopic").adminKeyName("adminKey").submitKeyName("submitKey"), + submitMessageTo("testTopic").message("message"), + updateTopic("testTopic").submitKey(EMPTY_KEY), + getTopicInfo("testTopic").hasNoSubmitKey().hasAdminKey("adminKey"), + submitMessageTo("testTopic").message("message").logged()); } @HapiTest final Stream updateAdminKeyToDiffKey() { - return defaultHapiSpec("updateAdminKeyToDiffKey") - .given( - newKeyNamed("adminKey"), - newKeyNamed("updateAdminKey"), - createTopic("testTopic").adminKeyName("adminKey")) - .when(updateTopic("testTopic").adminKey("updateAdminKey")) - .then(getTopicInfo("testTopic").hasAdminKey("updateAdminKey").logged()); + return hapiTest( + newKeyNamed("adminKey"), + newKeyNamed("updateAdminKey"), + createTopic("testTopic").adminKeyName("adminKey"), + updateTopic("testTopic").adminKey("updateAdminKey"), + getTopicInfo("testTopic").hasAdminKey("updateAdminKey").logged()); } @HapiTest final Stream updateAdminKeyToEmpty() { - return defaultHapiSpec("updateAdminKeyToEmpty") - .given(newKeyNamed("adminKey"), createTopic("testTopic").adminKeyName("adminKey")) + return hapiTest( + newKeyNamed("adminKey"), + createTopic("testTopic").adminKeyName("adminKey"), /* if adminKey is empty list should clear adminKey */ - .when(updateTopic("testTopic").adminKey(EMPTY_KEY)) - .then(getTopicInfo("testTopic").hasNoAdminKey().logged()); + updateTopic("testTopic").adminKey(EMPTY_KEY), + getTopicInfo("testTopic").hasNoAdminKey().logged()); } @HapiTest final Stream updateMultipleFields() { long expirationTimestamp = Instant.now().getEpochSecond() + 7999990; // more than default.autorenew // .secs=7000000 - return defaultHapiSpec("updateMultipleFields") - .given( - newKeyNamed("adminKey"), - newKeyNamed("adminKey2"), - newKeyNamed("submitKey"), - cryptoCreate("autoRenewAccount"), - cryptoCreate("nextAutoRenewAccount"), - createTopic("testTopic") - .topicMemo("initialmemo") - .adminKeyName("adminKey") - .autoRenewPeriod(validAutoRenewPeriod) - .autoRenewAccountId("autoRenewAccount")) - .when(updateTopic("testTopic") + return hapiTest( + newKeyNamed("adminKey"), + newKeyNamed("adminKey2"), + newKeyNamed("submitKey"), + cryptoCreate("autoRenewAccount"), + cryptoCreate("nextAutoRenewAccount"), + createTopic("testTopic") + .topicMemo("initialmemo") + .adminKeyName("adminKey") + .autoRenewPeriod(validAutoRenewPeriod) + .autoRenewAccountId("autoRenewAccount"), + updateTopic("testTopic") .topicMemo("updatedmemo") .submitKey("submitKey") .adminKey("adminKey2") .expiry(expirationTimestamp) .autoRenewPeriod(validAutoRenewPeriod + 5_000L) .autoRenewAccountId("nextAutoRenewAccount") - .hasKnownStatus(SUCCESS)) - .then(getTopicInfo("testTopic") + .hasKnownStatus(SUCCESS), + getTopicInfo("testTopic") .hasMemo("updatedmemo") .hasSubmitKey("submitKey") .hasAdminKey("adminKey2") @@ -231,16 +216,14 @@ final Stream updateMultipleFields() { @HapiTest final Stream expirationTimestampIsValidated() { long now = Instant.now().getEpochSecond(); - return defaultHapiSpec("expirationTimestampIsValidated") - .given(createTopic("testTopic").autoRenewPeriod(validAutoRenewPeriod)) - .when() - .then( - updateTopic("testTopic") - .expiry(now - 1) // less than consensus time - .hasKnownStatusFrom(INVALID_EXPIRATION_TIME, EXPIRATION_REDUCTION_NOT_ALLOWED), - updateTopic("testTopic") - .expiry(now + 1000) // 1000 < autoRenewPeriod - .hasKnownStatus(EXPIRATION_REDUCTION_NOT_ALLOWED)); + return hapiTest( + createTopic("testTopic").autoRenewPeriod(validAutoRenewPeriod), + updateTopic("testTopic") + .expiry(now - 1) // less than consensus time + .hasKnownStatusFrom(INVALID_EXPIRATION_TIME, EXPIRATION_REDUCTION_NOT_ALLOWED), + updateTopic("testTopic") + .expiry(now + 1000) // 1000 < autoRenewPeriod + .hasKnownStatus(EXPIRATION_REDUCTION_NOT_ALLOWED)); } /* If admin key is not set, only expiration timestamp updates are allowed */ @@ -260,39 +243,36 @@ final Stream updateExpiryOnTopicWithNoAdminKey() { @HapiTest final Stream clearingAdminKeyWhenAutoRenewAccountPresent() { - return defaultHapiSpec("clearingAdminKeyWhenAutoRenewAccountPresent") - .given( - newKeyNamed("adminKey"), - cryptoCreate("autoRenewAccount"), - createTopic("testTopic").adminKeyName("adminKey").autoRenewAccountId("autoRenewAccount")) - .when( - updateTopic("testTopic").adminKey(EMPTY_KEY).hasKnownStatus(AUTORENEW_ACCOUNT_NOT_ALLOWED), - updateTopic("testTopic").adminKey(EMPTY_KEY).autoRenewAccountId("0.0.0")) - .then(getTopicInfo("testTopic").hasNoAdminKey()); + return hapiTest( + newKeyNamed("adminKey"), + cryptoCreate("autoRenewAccount"), + createTopic("testTopic").adminKeyName("adminKey").autoRenewAccountId("autoRenewAccount"), + updateTopic("testTopic").adminKey(EMPTY_KEY).hasKnownStatus(AUTORENEW_ACCOUNT_NOT_ALLOWED), + updateTopic("testTopic").adminKey(EMPTY_KEY).autoRenewAccountId("0.0.0"), + getTopicInfo("testTopic").hasNoAdminKey()); } @HapiTest final Stream updateSubmitKeyOnTopicWithNoAdminKeyFails() { - return defaultHapiSpec("updateSubmitKeyOnTopicWithNoAdminKeyFails") - .given(newKeyNamed("submitKey"), createTopic("testTopic")) - .when(updateTopic("testTopic").submitKey("submitKey").hasKnownStatus(UNAUTHORIZED)) - .then(); + return hapiTest( + newKeyNamed("submitKey"), + createTopic("testTopic"), + updateTopic("testTopic").submitKey("submitKey").hasKnownStatus(UNAUTHORIZED)); } @HapiTest final Stream feeAsExpected() { - return defaultHapiSpec("feeAsExpected") - .given( - cryptoCreate("autoRenewAccount"), - cryptoCreate("payer"), - createTopic("testTopic") - .autoRenewAccountId("autoRenewAccount") - .autoRenewPeriod(THREE_MONTHS_IN_SECONDS - 1) - .adminKeyName("payer")) - .when(updateTopic("testTopic") + return hapiTest( + cryptoCreate("autoRenewAccount"), + cryptoCreate("payer"), + createTopic("testTopic") + .autoRenewAccountId("autoRenewAccount") + .autoRenewPeriod(THREE_MONTHS_IN_SECONDS - 1) + .adminKeyName("payer"), + updateTopic("testTopic") .payingWith("payer") .autoRenewPeriod(THREE_MONTHS_IN_SECONDS) - .via("updateTopic")) - .then(validateChargedUsdWithin("updateTopic", 0.00022, 3.0)); + .via("updateTopic"), + validateChargedUsdWithin("updateTopic", 0.00022, 3.0)); } } diff --git a/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/classiccalls/FailureCharacterizationSuite.java b/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/classiccalls/FailureCharacterizationSuite.java index ea2168d7d05f..2385142ba1af 100644 --- a/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/classiccalls/FailureCharacterizationSuite.java +++ b/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/classiccalls/FailureCharacterizationSuite.java @@ -16,7 +16,7 @@ package com.hedera.services.bdd.suites.contract.classiccalls; -import static com.hedera.services.bdd.spec.HapiSpec.defaultHapiSpec; +import static com.hedera.services.bdd.spec.HapiSpec.hapiTest; import static com.hedera.services.bdd.spec.keys.SigControl.ED25519_ON; import static com.hedera.services.bdd.spec.keys.SigControl.OFF; import static com.hedera.services.bdd.spec.keys.SigControl.ON; @@ -187,77 +187,70 @@ final Stream characterizeClassicFailureModes( } else { CALL_RESULTS_SNAPSHOT.load(); } - return defaultHapiSpec("CharacterizeClassicFailureModes") - .given(uploadInitCode(FAILABLE_CALLS_CONTRACT), contractCreate(FAILABLE_CALLS_CONTRACT)) - .when(classicInventoryIsAvailable()) - .then( - inParallel(Arrays.stream(ClassicFailureMode.values()) - .flatMap(mode -> calls.stream() - .filter(call -> call.hasFailureMode(mode)) - .map(call -> sourcingContextual(spec -> { - final var params = call.encodedCall(mode, spec); - final var nonStaticTxnId = "CALL-" + call.name() + "-" + mode.name(); - final var nonStaticCall = blockingOrder( - contractCall(FAILABLE_CALLS_CONTRACT, "makeClassicCall", params) - .via(nonStaticTxnId) - .gas(1_000_000L) - .hasKnownStatusFrom(SUCCESS, CONTRACT_REVERT_EXECUTED), - getTxnRecord(nonStaticTxnId).exposingAllTo(records -> { - final var actualResult = call.asCallResult(records); - if (characterizationMode - == CharacterizationMode.RECORD_SNAPSHOT) { - CALL_RESULTS_SNAPSHOT.recordResult( - call.name(), mode, actualResult); - } else { - final var expectedResult = - CALL_RESULTS_SNAPSHOT.expectedResultOf( - call.name(), mode); - assertEquals( - expectedResult, - actualResult, - "Wrong result for " + call.name() - + " for failure mode " + mode.name()); - } - })); - return !call.staticCallOk() - ? nonStaticCall - : blockingOrder( - nonStaticCall, - contractCallLocal( - FAILABLE_CALLS_CONTRACT, - "makeClassicCall", - params) - .hasAnswerOnlyPrecheckFrom( - OK, CONTRACT_REVERT_EXECUTED) - .exposingFullResultTo((status, result) -> { - final var actualResult = - call.asStaticCallResult(status, result); - if (characterizationMode - == CharacterizationMode - .RECORD_SNAPSHOT) { - CALL_RESULTS_SNAPSHOT.recordStaticResult( - call.name(), mode, actualResult); - } else { - final var expectedResult = - CALL_RESULTS_SNAPSHOT - .expectedStaticCallResultOf( - call.name(), mode); - assertEquals( - expectedResult, - actualResult, - "Wrong static call result for " - + call.name() - + " for failure mode " - + mode.name()); - } - })); - }))) - .toArray(HapiSpecOperation[]::new)), - withOpContext((spec, opLog) -> { - if (characterizationMode == CharacterizationMode.RECORD_SNAPSHOT) { - CALL_RESULTS_SNAPSHOT.commit(); - } - })); + return hapiTest( + uploadInitCode(FAILABLE_CALLS_CONTRACT), + contractCreate(FAILABLE_CALLS_CONTRACT), + classicInventoryIsAvailable(), + inParallel(Arrays.stream(ClassicFailureMode.values()) + .flatMap(mode -> calls.stream() + .filter(call -> call.hasFailureMode(mode)) + .map(call -> sourcingContextual(spec -> { + final var params = call.encodedCall(mode, spec); + final var nonStaticTxnId = "CALL-" + call.name() + "-" + mode.name(); + final var nonStaticCall = blockingOrder( + contractCall(FAILABLE_CALLS_CONTRACT, "makeClassicCall", params) + .via(nonStaticTxnId) + .gas(1_000_000L) + .hasKnownStatusFrom(SUCCESS, CONTRACT_REVERT_EXECUTED), + getTxnRecord(nonStaticTxnId).exposingAllTo(records -> { + final var actualResult = call.asCallResult(records); + if (characterizationMode == CharacterizationMode.RECORD_SNAPSHOT) { + CALL_RESULTS_SNAPSHOT.recordResult(call.name(), mode, actualResult); + } else { + final var expectedResult = + CALL_RESULTS_SNAPSHOT.expectedResultOf(call.name(), mode); + assertEquals( + expectedResult, + actualResult, + "Wrong result for " + call.name() + " for failure mode " + + mode.name()); + } + })); + return !call.staticCallOk() + ? nonStaticCall + : blockingOrder( + nonStaticCall, + contractCallLocal( + FAILABLE_CALLS_CONTRACT, "makeClassicCall", params) + .hasAnswerOnlyPrecheckFrom(OK, CONTRACT_REVERT_EXECUTED) + .exposingFullResultTo((status, result) -> { + final var actualResult = + call.asStaticCallResult(status, result); + if (characterizationMode + == CharacterizationMode.RECORD_SNAPSHOT) { + CALL_RESULTS_SNAPSHOT.recordStaticResult( + call.name(), mode, actualResult); + } else { + final var expectedResult = + CALL_RESULTS_SNAPSHOT + .expectedStaticCallResultOf( + call.name(), mode); + assertEquals( + expectedResult, + actualResult, + "Wrong static call result for " + + call.name() + + " for failure mode " + + mode.name()); + } + })); + }))) + .toArray(HapiSpecOperation[]::new)), + withOpContext((spec, opLog) -> { + if (characterizationMode == CharacterizationMode.RECORD_SNAPSHOT) { + CALL_RESULTS_SNAPSHOT.commit(); + } + })); } private HapiSpecOperation classicInventoryIsAvailable() { diff --git a/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/evm/Evm46ValidationSuite.java b/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/evm/Evm46ValidationSuite.java index e191887d9030..de49f6130b63 100644 --- a/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/evm/Evm46ValidationSuite.java +++ b/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/evm/Evm46ValidationSuite.java @@ -53,6 +53,7 @@ import static com.hedera.services.bdd.suites.HapiSuite.ONE_HBAR; import static com.hedera.services.bdd.suites.HapiSuite.ONE_HUNDRED_HBARS; import static com.hedera.services.bdd.suites.HapiSuite.SECP_256K1_SHAPE; +import static com.hedera.services.bdd.suites.HapiSuite.flattened; import static com.hedera.services.bdd.suites.contract.Utils.FunctionType.FUNCTION; import static com.hedera.services.bdd.suites.contract.Utils.asAddress; import static com.hedera.services.bdd.suites.contract.Utils.getABIFor; @@ -129,18 +130,17 @@ public class Evm46ValidationSuite { final Stream directCallToDeletedContractResultsInSuccessfulNoop() { AtomicReference receiverId = new AtomicReference<>(); - return defaultHapiSpec("directCallToDeletedContractResultsInSuccessfulNoop") - .given( - cryptoCreate(RECEIVER).exposingCreatedIdTo(receiverId::set), - uploadInitCode(INTERNAL_CALLER_CONTRACT), - contractCreate(INTERNAL_CALLER_CONTRACT) - // Refusing ethereum create conversion, because we get INVALID_SIGNATURE upon - // tokenAssociate, - // since we have CONTRACT_ID key - .refusingEthConversion() - .balance(ONE_HBAR), - contractDelete(INTERNAL_CALLER_CONTRACT)) - .when(withOpContext((spec, op) -> allRunFor( + return hapiTest( + cryptoCreate(RECEIVER).exposingCreatedIdTo(receiverId::set), + uploadInitCode(INTERNAL_CALLER_CONTRACT), + contractCreate(INTERNAL_CALLER_CONTRACT) + // Refusing ethereum create conversion, because we get INVALID_SIGNATURE upon + // tokenAssociate, + // since we have CONTRACT_ID key + .refusingEthConversion() + .balance(ONE_HBAR), + contractDelete(INTERNAL_CALLER_CONTRACT), + withOpContext((spec, op) -> allRunFor( spec, balanceSnapshot("initialBalance", asAccountString(receiverId.get())), contractCall( @@ -148,21 +148,19 @@ final Stream directCallToDeletedContractResultsInSuccessfulNoop() { CALL_WITH_VALUE_TO_FUNCTION, mirrorAddrWith(receiverId.get().getAccountNum())) .gas(GAS_LIMIT_FOR_CALL * 4) - .via(INNER_TXN)))) - .then( - getTxnRecord(INNER_TXN).hasPriority(recordWith().status(SUCCESS)), - getAccountBalance(RECEIVER).hasTinyBars(changeFromSnapshot("initialBalance", 0))); + .via(INNER_TXN))), + getTxnRecord(INNER_TXN).hasPriority(recordWith().status(SUCCESS)), + getAccountBalance(RECEIVER).hasTinyBars(changeFromSnapshot("initialBalance", 0))); } @HapiTest final Stream selfdestructToExistingMirrorAddressResultsInSuccess() { AtomicReference receiverId = new AtomicReference<>(); - return defaultHapiSpec("selfdestructToExistingMirrorAddressResultsInSuccess") - .given( - cryptoCreate(RECEIVER).exposingCreatedIdTo(receiverId::set), - uploadInitCode(INTERNAL_CALLER_CONTRACT), - contractCreate(INTERNAL_CALLER_CONTRACT).balance(ONE_HBAR)) - .when(withOpContext((spec, op) -> { + return hapiTest( + cryptoCreate(RECEIVER).exposingCreatedIdTo(receiverId::set), + uploadInitCode(INTERNAL_CALLER_CONTRACT), + contractCreate(INTERNAL_CALLER_CONTRACT).balance(ONE_HBAR), + withOpContext((spec, op) -> { allRunFor( spec, balanceSnapshot("selfdestructTargetAccount", asAccountString(receiverId.get())), @@ -172,21 +170,19 @@ final Stream selfdestructToExistingMirrorAddressResultsInSuccess() mirrorAddrWith(receiverId.get().getAccountNum())) .gas(GAS_LIMIT_FOR_CALL * 4) .via(INNER_TXN)); - })) - .then(getAccountBalance(RECEIVER) - .hasTinyBars(changeFromSnapshot("selfdestructTargetAccount", 100000000))); + }), + getAccountBalance(RECEIVER).hasTinyBars(changeFromSnapshot("selfdestructTargetAccount", 100000000))); } @HapiTest final Stream selfdestructToExistingNonMirrorAddressResultsInSuccess() { - return defaultHapiSpec("selfdestructToExistingNonMirrorAddressResultsInSuccess") - .given( - newKeyNamed(ECDSA_KEY).shape(SECP_256K1_SHAPE), - cryptoTransfer(tinyBarsFromAccountToAlias(GENESIS, ECDSA_KEY, ONE_HUNDRED_HBARS)), - withOpContext((spec, opLog) -> updateSpecFor(spec, ECDSA_KEY)), - uploadInitCode(INTERNAL_CALLER_CONTRACT), - contractCreate(INTERNAL_CALLER_CONTRACT).balance(ONE_HBAR)) - .when(withOpContext((spec, op) -> { + return hapiTest( + newKeyNamed(ECDSA_KEY).shape(SECP_256K1_SHAPE), + cryptoTransfer(tinyBarsFromAccountToAlias(GENESIS, ECDSA_KEY, ONE_HUNDRED_HBARS)), + withOpContext((spec, opLog) -> updateSpecFor(spec, ECDSA_KEY)), + uploadInitCode(INTERNAL_CALLER_CONTRACT), + contractCreate(INTERNAL_CALLER_CONTRACT).balance(ONE_HBAR), + withOpContext((spec, op) -> { final var ecdsaKey = spec.registry().getKey(ECDSA_KEY); final var tmp = ecdsaKey.getECDSASecp256K1().toByteArray(); final var addressBytes = recoverAddressFromPubKey(tmp); @@ -197,27 +193,25 @@ final Stream selfdestructToExistingNonMirrorAddressResultsInSuccess contractCall(INTERNAL_CALLER_CONTRACT, SELFDESTRUCT, asHeadlongAddress(addressBytes)) .gas(GAS_LIMIT_FOR_CALL * 4) .via(INNER_TXN)); - })) - .then(getAccountBalance(ECDSA_KEY) - .hasTinyBars(changeFromSnapshot("selfdestructTargetAccount", 100000000))); + }), + getAccountBalance(ECDSA_KEY).hasTinyBars(changeFromSnapshot("selfdestructTargetAccount", 100000000))); } @HapiTest final Stream selfdestructToNonExistingNonMirrorAddressResultsInInvalidSolidityAddress() { AtomicReference nonExistingNonMirrorAddress = new AtomicReference<>(); - return defaultHapiSpec("selfdestructToNonExistingNonMirrorAddressResultsInInvalidSolidityAddress") - .given( - newKeyNamed(ECDSA_KEY).shape(SECP_256K1_SHAPE), - withOpContext((spec, op) -> { - final var ecdsaKey = spec.registry().getKey(ECDSA_KEY); - final var tmp = ecdsaKey.getECDSASecp256K1().toByteArray(); - final var addressBytes = recoverAddressFromPubKey(tmp); - nonExistingNonMirrorAddress.set(Bytes.of(addressBytes)); - }), - uploadInitCode(INTERNAL_CALLER_CONTRACT), - contractCreate(INTERNAL_CALLER_CONTRACT).balance(ONE_HBAR)) - .when(withOpContext((spec, op) -> allRunFor( + return hapiTest( + newKeyNamed(ECDSA_KEY).shape(SECP_256K1_SHAPE), + withOpContext((spec, op) -> { + final var ecdsaKey = spec.registry().getKey(ECDSA_KEY); + final var tmp = ecdsaKey.getECDSASecp256K1().toByteArray(); + final var addressBytes = recoverAddressFromPubKey(tmp); + nonExistingNonMirrorAddress.set(Bytes.of(addressBytes)); + }), + uploadInitCode(INTERNAL_CALLER_CONTRACT), + contractCreate(INTERNAL_CALLER_CONTRACT).balance(ONE_HBAR), + withOpContext((spec, op) -> allRunFor( spec, contractCall( INTERNAL_CALLER_CONTRACT, @@ -227,8 +221,8 @@ final Stream selfdestructToNonExistingNonMirrorAddressResultsInInva .toArray())) .gas(ENOUGH_GAS_LIMIT_FOR_CREATION) .via(INNER_TXN) - .hasKnownStatus(INVALID_SOLIDITY_ADDRESS)))) - .then(getTxnRecord(INNER_TXN) + .hasKnownStatus(INVALID_SOLIDITY_ADDRESS))), + getTxnRecord(INNER_TXN) .hasPriority(recordWith() .status(INVALID_SOLIDITY_ADDRESS) .contractCallResult(resultWith().gasUsed(900000)))); @@ -236,11 +230,10 @@ final Stream selfdestructToNonExistingNonMirrorAddressResultsInInva @HapiTest final Stream selfdestructToNonExistingMirrorAddressResultsInInvalidSolidityAddress() { - return defaultHapiSpec("selfdestructToNonExistingMirrorAddressResultsInInvalidSolidityAddress") - .given( - uploadInitCode(INTERNAL_CALLER_CONTRACT), - contractCreate(INTERNAL_CALLER_CONTRACT).balance(ONE_HBAR)) - .when(withOpContext((spec, op) -> allRunFor( + return hapiTest( + uploadInitCode(INTERNAL_CALLER_CONTRACT), + contractCreate(INTERNAL_CALLER_CONTRACT).balance(ONE_HBAR), + withOpContext((spec, op) -> allRunFor( spec, contractCall( INTERNAL_CALLER_CONTRACT, @@ -248,8 +241,8 @@ final Stream selfdestructToNonExistingMirrorAddressResultsInInvalid mirrorAddrWith(FIRST_NONEXISTENT_CONTRACT_NUM)) .gas(ENOUGH_GAS_LIMIT_FOR_CREATION) .via(INNER_TXN) - .hasKnownStatus(INVALID_SOLIDITY_ADDRESS)))) - .then(getTxnRecord(INNER_TXN) + .hasKnownStatus(INVALID_SOLIDITY_ADDRESS))), + getTxnRecord(INNER_TXN) .hasPriority(recordWith() .status(INVALID_SOLIDITY_ADDRESS) .contractCallResult(resultWith().gasUsed(900000)))); @@ -258,12 +251,12 @@ final Stream selfdestructToNonExistingMirrorAddressResultsInInvalid @HapiTest final Stream directCallToNonExistingMirrorAddressResultsInSuccessfulNoOp() { - return defaultHapiSpec("directCallToNonExistingMirrorAddressResultsInSuccessfulNoOp") - .given(withOpContext((spec, ctxLog) -> spec.registry() + return hapiTest( + withOpContext((spec, ctxLog) -> spec.registry() .saveContractId( "nonExistingMirrorAddress", - asContractIdWithEvmAddress(ByteString.copyFrom(unhex(NON_EXISTING_MIRROR_ADDRESS)))))) - .when(withOpContext((spec, ctxLog) -> allRunFor( + asContractIdWithEvmAddress(ByteString.copyFrom(unhex(NON_EXISTING_MIRROR_ADDRESS))))), + withOpContext((spec, ctxLog) -> allRunFor( spec, contractCallWithFunctionAbi("nonExistingMirrorAddress", getABIFor(FUNCTION, NAME, ERC_721_ABI)) .gas(GAS_LIMIT_FOR_CALL) @@ -271,31 +264,30 @@ final Stream directCallToNonExistingMirrorAddressResultsInSuccessfu // attempt call again, make sure the result is the same contractCallWithFunctionAbi("nonExistingMirrorAddress", getABIFor(FUNCTION, NAME, ERC_721_ABI)) .gas(GAS_LIMIT_FOR_CALL) - .via("directCallToNonExistingMirrorAddress2")))) - .then( - getTxnRecord("directCallToNonExistingMirrorAddress") - .hasPriority(recordWith() - .status(SUCCESS) - .contractCallResult(resultWith() - .gasUsed(INTRINSIC_GAS_COST + EXTRA_GAS_FOR_FUNCTION_SELECTOR))), - getTxnRecord("directCallToNonExistingMirrorAddress2") - .hasPriority(recordWith() - .status(SUCCESS) - .contractCallResult(resultWith() - .gasUsed(INTRINSIC_GAS_COST + EXTRA_GAS_FOR_FUNCTION_SELECTOR))), - getContractInfo("nonExistingMirrorAddress").hasCostAnswerPrecheck(INVALID_CONTRACT_ID)); + .via("directCallToNonExistingMirrorAddress2"))), + getTxnRecord("directCallToNonExistingMirrorAddress") + .hasPriority(recordWith() + .status(SUCCESS) + .contractCallResult( + resultWith().gasUsed(INTRINSIC_GAS_COST + EXTRA_GAS_FOR_FUNCTION_SELECTOR))), + getTxnRecord("directCallToNonExistingMirrorAddress2") + .hasPriority(recordWith() + .status(SUCCESS) + .contractCallResult( + resultWith().gasUsed(INTRINSIC_GAS_COST + EXTRA_GAS_FOR_FUNCTION_SELECTOR))), + getContractInfo("nonExistingMirrorAddress").hasCostAnswerPrecheck(INVALID_CONTRACT_ID)); } @HapiTest final Stream directCallToNonExistingNonMirrorAddressResultsInSuccessfulNoOp() { - return defaultHapiSpec("directCallToNonExistingNonMirrorAddressResultsInSuccessfulNoOp") - .given(withOpContext((spec, ctxLog) -> spec.registry() + return hapiTest( + withOpContext((spec, ctxLog) -> spec.registry() .saveContractId( "nonExistingNonMirrorAddress", asContractIdWithEvmAddress( - ByteString.copyFrom(unhex(NON_EXISTING_NON_MIRROR_ADDRESS)))))) - .when(withOpContext((spec, ctxLog) -> allRunFor( + ByteString.copyFrom(unhex(NON_EXISTING_NON_MIRROR_ADDRESS))))), + withOpContext((spec, ctxLog) -> allRunFor( spec, contractCallWithFunctionAbi( "nonExistingNonMirrorAddress", getABIFor(FUNCTION, NAME, ERC_721_ABI)) @@ -305,33 +297,33 @@ final Stream directCallToNonExistingNonMirrorAddressResultsInSucces contractCallWithFunctionAbi( "nonExistingNonMirrorAddress", getABIFor(FUNCTION, NAME, ERC_721_ABI)) .gas(GAS_LIMIT_FOR_CALL) - .via("directCallToNonExistingNonMirrorAddress2")))) - .then( - getTxnRecord("directCallToNonExistingNonMirrorAddress") - .hasPriority(recordWith() - .status(SUCCESS) - .contractCallResult(resultWith() - .gasUsed(INTRINSIC_GAS_COST + EXTRA_GAS_FOR_FUNCTION_SELECTOR))), - getTxnRecord("directCallToNonExistingNonMirrorAddress2") - .hasPriority(recordWith() - .status(SUCCESS) - .contractCallResult(resultWith() - .gasUsed(INTRINSIC_GAS_COST + EXTRA_GAS_FOR_FUNCTION_SELECTOR))), - getContractInfo("nonExistingNonMirrorAddress").hasCostAnswerPrecheck(INVALID_CONTRACT_ID)); + .via("directCallToNonExistingNonMirrorAddress2"))), + getTxnRecord("directCallToNonExistingNonMirrorAddress") + .hasPriority(recordWith() + .status(SUCCESS) + .contractCallResult( + resultWith().gasUsed(INTRINSIC_GAS_COST + EXTRA_GAS_FOR_FUNCTION_SELECTOR))), + getTxnRecord("directCallToNonExistingNonMirrorAddress2") + .hasPriority(recordWith() + .status(SUCCESS) + .contractCallResult( + resultWith().gasUsed(INTRINSIC_GAS_COST + EXTRA_GAS_FOR_FUNCTION_SELECTOR))), + getContractInfo("nonExistingNonMirrorAddress").hasCostAnswerPrecheck(INVALID_CONTRACT_ID)); } @HapiTest final Stream directCallToRevertingContractRevertsWithCorrectRevertReason() { - return defaultHapiSpec("directCallToRevertingContractRevertsWithCorrectRevertReason") - .given(uploadInitCode(INTERNAL_CALLEE_CONTRACT), contractCreate(INTERNAL_CALLEE_CONTRACT)) - .when(withOpContext((spec, ctxLog) -> allRunFor( + return hapiTest( + uploadInitCode(INTERNAL_CALLEE_CONTRACT), + contractCreate(INTERNAL_CALLEE_CONTRACT), + withOpContext((spec, ctxLog) -> allRunFor( spec, contractCall(INTERNAL_CALLEE_CONTRACT, REVERT_WITH_REVERT_REASON_FUNCTION) .gas(GAS_LIMIT_FOR_CALL) .via(INNER_TXN) - .hasKnownStatusFrom(CONTRACT_REVERT_EXECUTED)))) - .then(getTxnRecord(INNER_TXN) + .hasKnownStatusFrom(CONTRACT_REVERT_EXECUTED))), + getTxnRecord(INNER_TXN) .hasPriority(recordWith() .status(CONTRACT_REVERT_EXECUTED) .contractCallResult(resultWith() @@ -346,47 +338,42 @@ final Stream directCallToExistingCryptoAccountResultsInSuccess() { AtomicReference mirrorAccountID = new AtomicReference<>(); - return defaultHapiSpec("directCallToExistingCryptoAccountResultsInSuccess") - .given( - newKeyNamed(ECDSA_KEY).shape(SECP_256K1_SHAPE), - cryptoCreate("MirrorAccount") - .balance(ONE_HUNDRED_HBARS) - .exposingCreatedIdTo(mirrorAccountID::set), - cryptoTransfer(tinyBarsFromAccountToAlias(GENESIS, ECDSA_KEY, ONE_HUNDRED_HBARS)), - withOpContext((spec, opLog) -> { - spec.registry() - .saveContractId( - "mirrorAddress", - asContract("0.0." - + mirrorAccountID.get().getAccountNum())); - updateSpecFor(spec, ECDSA_KEY); - spec.registry() - .saveContractId( - "nonMirrorAddress", - asContract("0.0." - + spec.registry() - .getAccountID(ECDSA_KEY) - .getAccountNum())); - })) - .when(withOpContext((spec, ctxLog) -> allRunFor( + return hapiTest( + newKeyNamed(ECDSA_KEY).shape(SECP_256K1_SHAPE), + cryptoCreate("MirrorAccount").balance(ONE_HUNDRED_HBARS).exposingCreatedIdTo(mirrorAccountID::set), + cryptoTransfer(tinyBarsFromAccountToAlias(GENESIS, ECDSA_KEY, ONE_HUNDRED_HBARS)), + withOpContext((spec, opLog) -> { + spec.registry() + .saveContractId( + "mirrorAddress", + asContract("0.0." + mirrorAccountID.get().getAccountNum())); + updateSpecFor(spec, ECDSA_KEY); + spec.registry() + .saveContractId( + "nonMirrorAddress", + asContract("0.0." + + spec.registry() + .getAccountID(ECDSA_KEY) + .getAccountNum())); + }), + withOpContext((spec, ctxLog) -> allRunFor( spec, contractCallWithFunctionAbi("mirrorAddress", getABIFor(FUNCTION, NAME, ERC_721_ABI)) .gas(GAS_LIMIT_FOR_CALL) .via("callToMirrorAddress"), contractCallWithFunctionAbi("nonMirrorAddress", getABIFor(FUNCTION, NAME, ERC_721_ABI)) .gas(GAS_LIMIT_FOR_CALL) - .via("callToNonMirrorAddress")))) - .then( - getTxnRecord("callToMirrorAddress") - .hasPriority(recordWith() - .status(SUCCESS) - .contractCallResult(resultWith() - .gasUsed(INTRINSIC_GAS_COST + EXTRA_GAS_FOR_FUNCTION_SELECTOR))), - getTxnRecord("callToNonMirrorAddress") - .hasPriority(recordWith() - .status(SUCCESS) - .contractCallResult(resultWith() - .gasUsed(INTRINSIC_GAS_COST + EXTRA_GAS_FOR_FUNCTION_SELECTOR)))); + .via("callToNonMirrorAddress"))), + getTxnRecord("callToMirrorAddress") + .hasPriority(recordWith() + .status(SUCCESS) + .contractCallResult( + resultWith().gasUsed(INTRINSIC_GAS_COST + EXTRA_GAS_FOR_FUNCTION_SELECTOR))), + getTxnRecord("callToNonMirrorAddress") + .hasPriority(recordWith() + .status(SUCCESS) + .contractCallResult( + resultWith().gasUsed(INTRINSIC_GAS_COST + EXTRA_GAS_FOR_FUNCTION_SELECTOR)))); } @HapiTest @@ -394,41 +381,37 @@ final Stream directCallWithValueToExistingCryptoAccountResultsInSuc AtomicReference mirrorAccountID = new AtomicReference<>(); - return defaultHapiSpec("directCallWithValueToExistingCryptoAccountResultsInSuccess") - .given( - newKeyNamed(ECDSA_KEY).shape(SECP_256K1_SHAPE), - cryptoCreate("MirrorAccount") - .balance(ONE_HUNDRED_HBARS) - .exposingCreatedIdTo(mirrorAccountID::set), - cryptoTransfer(tinyBarsFromAccountToAlias(GENESIS, ECDSA_KEY, ONE_HUNDRED_HBARS)), - withOpContext((spec, opLog) -> { - spec.registry() - .saveContractId( - "mirrorAddress", - asContract("0.0." - + mirrorAccountID.get().getAccountNum())); - updateSpecFor(spec, ECDSA_KEY); - final var ecdsaKey = spec.registry() - .getKey(ECDSA_KEY) - .getECDSASecp256K1() - .toByteArray(); - final var senderAddress = ByteString.copyFrom(recoverAddressFromPubKey(ecdsaKey)); - spec.registry() - .saveContractId( - "nonMirrorAddress", - ContractID.newBuilder() - .setEvmAddress(senderAddress) - .build()); - spec.registry() - .saveAccountId( - "NonMirrorAccount", - AccountID.newBuilder() - .setAccountNum(spec.registry() - .getAccountID(ECDSA_KEY) - .getAccountNum()) - .build()); - })) - .when(withOpContext((spec, ctxLog) -> allRunFor( + return hapiTest( + newKeyNamed(ECDSA_KEY).shape(SECP_256K1_SHAPE), + cryptoCreate("MirrorAccount").balance(ONE_HUNDRED_HBARS).exposingCreatedIdTo(mirrorAccountID::set), + cryptoTransfer(tinyBarsFromAccountToAlias(GENESIS, ECDSA_KEY, ONE_HUNDRED_HBARS)), + withOpContext((spec, opLog) -> { + spec.registry() + .saveContractId( + "mirrorAddress", + asContract("0.0." + mirrorAccountID.get().getAccountNum())); + updateSpecFor(spec, ECDSA_KEY); + final var ecdsaKey = spec.registry() + .getKey(ECDSA_KEY) + .getECDSASecp256K1() + .toByteArray(); + final var senderAddress = ByteString.copyFrom(recoverAddressFromPubKey(ecdsaKey)); + spec.registry() + .saveContractId( + "nonMirrorAddress", + ContractID.newBuilder() + .setEvmAddress(senderAddress) + .build()); + spec.registry() + .saveAccountId( + "NonMirrorAccount", + AccountID.newBuilder() + .setAccountNum(spec.registry() + .getAccountID(ECDSA_KEY) + .getAccountNum()) + .build()); + }), + withOpContext((spec, ctxLog) -> allRunFor( spec, balanceSnapshot("mirrorSnapshot", "MirrorAccount"), balanceSnapshot("nonMirrorSnapshot", "NonMirrorAccount"), @@ -439,37 +422,34 @@ final Stream directCallWithValueToExistingCryptoAccountResultsInSuc contractCallWithFunctionAbi("nonMirrorAddress", getABIFor(FUNCTION, NAME, ERC_721_ABI)) .sending(ONE_HBAR) .gas(GAS_LIMIT_FOR_CALL) - .via("callToNonMirrorAddress")))) - .then( - getTxnRecord("callToMirrorAddress") - .hasPriority(recordWith() - .status(SUCCESS) - .contractCallResult(resultWith() - .gasUsed(INTRINSIC_GAS_COST + EXTRA_GAS_FOR_FUNCTION_SELECTOR))), - getTxnRecord("callToNonMirrorAddress") - .hasPriority(recordWith() - .status(SUCCESS) - .contractCallResult(resultWith() - .gasUsed(INTRINSIC_GAS_COST + EXTRA_GAS_FOR_FUNCTION_SELECTOR))), - getAccountBalance("MirrorAccount").hasTinyBars(changeFromSnapshot("mirrorSnapshot", ONE_HBAR)), - getAccountBalance("NonMirrorAccount") - .hasTinyBars(changeFromSnapshot("nonMirrorSnapshot", ONE_HBAR))); + .via("callToNonMirrorAddress"))), + getTxnRecord("callToMirrorAddress") + .hasPriority(recordWith() + .status(SUCCESS) + .contractCallResult( + resultWith().gasUsed(INTRINSIC_GAS_COST + EXTRA_GAS_FOR_FUNCTION_SELECTOR))), + getTxnRecord("callToNonMirrorAddress") + .hasPriority(recordWith() + .status(SUCCESS) + .contractCallResult( + resultWith().gasUsed(INTRINSIC_GAS_COST + EXTRA_GAS_FOR_FUNCTION_SELECTOR))), + getAccountBalance("MirrorAccount").hasTinyBars(changeFromSnapshot("mirrorSnapshot", ONE_HBAR)), + getAccountBalance("NonMirrorAccount").hasTinyBars(changeFromSnapshot("nonMirrorSnapshot", ONE_HBAR))); } @HapiTest final Stream internalCallToNonExistingMirrorAddressResultsInNoopSuccess() { - return defaultHapiSpec("internalCallToNonExistingMirrorAddressResultsInNoopSuccess") - .given( - uploadInitCode(INTERNAL_CALLER_CONTRACT), - contractCreate(INTERNAL_CALLER_CONTRACT).balance(ONE_HBAR)) - .when(contractCall( + return hapiTest( + uploadInitCode(INTERNAL_CALLER_CONTRACT), + contractCreate(INTERNAL_CALLER_CONTRACT).balance(ONE_HBAR), + contractCall( INTERNAL_CALLER_CONTRACT, CALL_NON_EXISTING_FUNCTION, mirrorAddrWith(FIRST_NONEXISTENT_CONTRACT_NUM + 1)) .gas(GAS_LIMIT_FOR_CALL) - .via(INNER_TXN)) - .then(getTxnRecord(INNER_TXN) + .via(INNER_TXN), + getTxnRecord(INNER_TXN) .hasPriority(recordWith() .status(SUCCESS) .contractCallResult( @@ -481,23 +461,22 @@ final Stream internalCallToExistingMirrorAddressResultsInSuccessful final AtomicLong calleeNum = new AtomicLong(); - return defaultHapiSpec("internalCallToExistingMirrorAddressResultsInSuccessfulCall") - .given( - uploadInitCode(INTERNAL_CALLER_CONTRACT, INTERNAL_CALLEE_CONTRACT), - contractCreate(INTERNAL_CALLER_CONTRACT) - .balance(ONE_HBAR) - // Adding refusingEthConversion() due to fee differences and not supported address type - .refusingEthConversion(), - contractCreate(INTERNAL_CALLEE_CONTRACT) - .exposingNumTo(calleeNum::set) - // Adding refusingEthConversion() due to fee differences and not supported address type - .refusingEthConversion()) - .when(withOpContext((spec, ignored) -> allRunFor( + return hapiTest( + uploadInitCode(INTERNAL_CALLER_CONTRACT, INTERNAL_CALLEE_CONTRACT), + contractCreate(INTERNAL_CALLER_CONTRACT) + .balance(ONE_HBAR) + // Adding refusingEthConversion() due to fee differences and not supported address type + .refusingEthConversion(), + contractCreate(INTERNAL_CALLEE_CONTRACT) + .exposingNumTo(calleeNum::set) + // Adding refusingEthConversion() due to fee differences and not supported address type + .refusingEthConversion(), + withOpContext((spec, ignored) -> allRunFor( spec, contractCall(INTERNAL_CALLER_CONTRACT, CALL_EXTERNAL_FUNCTION, mirrorAddrWith(calleeNum.get())) .gas(GAS_LIMIT_FOR_CALL * 2) - .via(INNER_TXN)))) - .then(getTxnRecord(INNER_TXN) + .via(INNER_TXN))), + getTxnRecord(INNER_TXN) .hasPriority(recordWith() .status(SUCCESS) .contractCallResult(resultWith() @@ -509,17 +488,16 @@ final Stream internalCallToExistingMirrorAddressResultsInSuccessful @HapiTest final Stream internalCallToNonExistingNonMirrorAddressResultsInNoopSuccess() { - return defaultHapiSpec("internalCallToNonExistingNonMirrorAddressResultsInNoopSuccess") - .given( - uploadInitCode(INTERNAL_CALLER_CONTRACT), - contractCreate(INTERNAL_CALLER_CONTRACT).balance(ONE_HBAR)) - .when(contractCall( + return hapiTest( + uploadInitCode(INTERNAL_CALLER_CONTRACT), + contractCreate(INTERNAL_CALLER_CONTRACT).balance(ONE_HBAR), + contractCall( INTERNAL_CALLER_CONTRACT, CALL_NON_EXISTING_FUNCTION, nonMirrorAddrWith(FIRST_NONEXISTENT_CONTRACT_NUM + 2)) .gas(GAS_LIMIT_FOR_CALL) - .via(INNER_TXN)) - .then(getTxnRecord(INNER_TXN) + .via(INNER_TXN), + getTxnRecord(INNER_TXN) .hasPriority(recordWith() .status(SUCCESS) .contractCallResult( @@ -531,12 +509,11 @@ final Stream internalCallToExistingRevertingResultsInSuccessfulTopL final AtomicLong calleeNum = new AtomicLong(); - return defaultHapiSpec("internalCallToExistingRevertingWithoutMessageResultsInSuccessfulTopLevelTxn") - .given( - uploadInitCode(INTERNAL_CALLER_CONTRACT, INTERNAL_CALLEE_CONTRACT), - contractCreate(INTERNAL_CALLER_CONTRACT).balance(ONE_HBAR), - contractCreate(INTERNAL_CALLEE_CONTRACT).exposingNumTo(calleeNum::set)) - .when(withOpContext((spec, ignored) -> allRunFor( + return hapiTest( + uploadInitCode(INTERNAL_CALLER_CONTRACT, INTERNAL_CALLEE_CONTRACT), + contractCreate(INTERNAL_CALLER_CONTRACT).balance(ONE_HBAR), + contractCreate(INTERNAL_CALLEE_CONTRACT).exposingNumTo(calleeNum::set), + withOpContext((spec, ignored) -> allRunFor( spec, contractCall( INTERNAL_CALLER_CONTRACT, @@ -544,23 +521,22 @@ final Stream internalCallToExistingRevertingResultsInSuccessfulTopL mirrorAddrWith(calleeNum.get())) .gas(GAS_LIMIT_FOR_CALL * 8) .hasKnownStatus(SUCCESS) - .via(INNER_TXN)))) - .then(getTxnRecord(INNER_TXN).hasPriority(recordWith().status(SUCCESS))); + .via(INNER_TXN))), + getTxnRecord(INNER_TXN).hasPriority(recordWith().status(SUCCESS))); } @HapiTest final Stream internalTransferToNonExistingMirrorAddressResultsInInvalidAliasKey() { - return defaultHapiSpec("internalTransferToNonExistingMirrorAddressResultsInInvalidAliasKey") - .given( - uploadInitCode(INTERNAL_CALLER_CONTRACT), - contractCreate(INTERNAL_CALLER_CONTRACT).balance(ONE_HBAR)) - .when(contractCall( + return hapiTest( + uploadInitCode(INTERNAL_CALLER_CONTRACT), + contractCreate(INTERNAL_CALLER_CONTRACT).balance(ONE_HBAR), + contractCall( INTERNAL_CALLER_CONTRACT, TRANSFER_TO_FUNCTION, mirrorAddrWith(FIRST_NONEXISTENT_CONTRACT_NUM + 3)) .gas(GAS_LIMIT_FOR_CALL * 4) - .hasKnownStatus(CONTRACT_REVERT_EXECUTED)) - .then(getAccountBalance("0.0." + (FIRST_NONEXISTENT_CONTRACT_NUM + 3)) + .hasKnownStatus(CONTRACT_REVERT_EXECUTED), + getAccountBalance("0.0." + (FIRST_NONEXISTENT_CONTRACT_NUM + 3)) .nodePayment(ONE_HBAR) .hasAnswerOnlyPrecheck(INVALID_ACCOUNT_ID)); } @@ -570,12 +546,11 @@ final Stream internalTransferToExistingMirrorAddressResultsInSucces AtomicReference receiverId = new AtomicReference<>(); - return defaultHapiSpec("internalTransferToExistingMirrorAddressResultsInSuccess") - .given( - cryptoCreate(RECEIVER).exposingCreatedIdTo(receiverId::set), - uploadInitCode(INTERNAL_CALLER_CONTRACT), - contractCreate(INTERNAL_CALLER_CONTRACT).balance(ONE_HBAR)) - .when(withOpContext((spec, op) -> allRunFor( + return hapiTest( + cryptoCreate(RECEIVER).exposingCreatedIdTo(receiverId::set), + uploadInitCode(INTERNAL_CALLER_CONTRACT), + contractCreate(INTERNAL_CALLER_CONTRACT).balance(ONE_HBAR), + withOpContext((spec, op) -> allRunFor( spec, balanceSnapshot("initialBalance", asAccountString(receiverId.get())), contractCall( @@ -583,43 +558,40 @@ final Stream internalTransferToExistingMirrorAddressResultsInSucces TRANSFER_TO_FUNCTION, mirrorAddrWith(receiverId.get().getAccountNum())) .gas(GAS_LIMIT_FOR_CALL * 4) - .via(INNER_TXN)))) - .then( - getTxnRecord(INNER_TXN) - .hasPriority(recordWith() - .transfers(including(tinyBarsFromTo(INTERNAL_CALLER_CONTRACT, RECEIVER, 1)))), - getAccountBalance(RECEIVER).hasTinyBars(changeFromSnapshot("initialBalance", 1))); + .via(INNER_TXN))), + getTxnRecord(INNER_TXN) + .hasPriority(recordWith() + .transfers(including(tinyBarsFromTo(INTERNAL_CALLER_CONTRACT, RECEIVER, 1)))), + getAccountBalance(RECEIVER).hasTinyBars(changeFromSnapshot("initialBalance", 1))); } @HapiTest final Stream internalTransferToNonExistingNonMirrorAddressResultsInRevert() { - return defaultHapiSpec("internalTransferToNonExistingNonMirrorAddressResultsInRevert") - .given( - cryptoCreate(CUSTOM_PAYER).balance(ONE_HUNDRED_HBARS), - uploadInitCode(INTERNAL_CALLER_CONTRACT), - contractCreate(INTERNAL_CALLER_CONTRACT).balance(ONE_HBAR)) - .when(contractCall( + return hapiTest( + cryptoCreate(CUSTOM_PAYER).balance(ONE_HUNDRED_HBARS), + uploadInitCode(INTERNAL_CALLER_CONTRACT), + contractCreate(INTERNAL_CALLER_CONTRACT).balance(ONE_HBAR), + contractCall( INTERNAL_CALLER_CONTRACT, TRANSFER_TO_FUNCTION, nonMirrorAddrWith(FIRST_NONEXISTENT_CONTRACT_NUM + 4)) .gas(GAS_LIMIT_FOR_CALL * 4) .payingWith(CUSTOM_PAYER) .via(INNER_TXN) - .hasKnownStatus(CONTRACT_REVERT_EXECUTED)) - .then(getTxnRecord(INNER_TXN).hasPriority(recordWith().status(CONTRACT_REVERT_EXECUTED))); + .hasKnownStatus(CONTRACT_REVERT_EXECUTED), + getTxnRecord(INNER_TXN).hasPriority(recordWith().status(CONTRACT_REVERT_EXECUTED))); } @HapiTest final Stream internalTransferToExistingNonMirrorAddressResultsInSuccess() { - return defaultHapiSpec("internalTransferToExistingNonMirrorAddressResultsInSuccess") - .given( - newKeyNamed(ECDSA_KEY).shape(SECP_256K1_SHAPE), - cryptoTransfer(tinyBarsFromAccountToAlias(GENESIS, ECDSA_KEY, ONE_HUNDRED_HBARS)), - withOpContext((spec, opLog) -> updateSpecFor(spec, ECDSA_KEY)), - uploadInitCode(INTERNAL_CALLER_CONTRACT), - contractCreate(INTERNAL_CALLER_CONTRACT).balance(ONE_HBAR)) - .when(withOpContext((spec, op) -> { + return hapiTest( + newKeyNamed(ECDSA_KEY).shape(SECP_256K1_SHAPE), + cryptoTransfer(tinyBarsFromAccountToAlias(GENESIS, ECDSA_KEY, ONE_HUNDRED_HBARS)), + withOpContext((spec, opLog) -> updateSpecFor(spec, ECDSA_KEY)), + uploadInitCode(INTERNAL_CALLER_CONTRACT), + contractCreate(INTERNAL_CALLER_CONTRACT).balance(ONE_HBAR), + withOpContext((spec, op) -> { final var ecdsaKey = spec.registry().getKey(ECDSA_KEY); final var tmp = ecdsaKey.getECDSASecp256K1().toByteArray(); final var addressBytes = recoverAddressFromPubKey(tmp); @@ -632,28 +604,25 @@ final Stream internalTransferToExistingNonMirrorAddressResultsInSuc asHeadlongAddress(addressBytes)) .gas(GAS_LIMIT_FOR_CALL * 4) .via(INNER_TXN)); - })) - .then( - getTxnRecord(INNER_TXN) - .hasPriority(recordWith() - .transfers(including(tinyBarsFromTo(INTERNAL_CALLER_CONTRACT, ECDSA_KEY, 1)))), - getAutoCreatedAccountBalance(ECDSA_KEY) - .hasTinyBars(changeFromSnapshot("autoCreatedSnapshot", 1))); + }), + getTxnRecord(INNER_TXN) + .hasPriority(recordWith() + .transfers(including(tinyBarsFromTo(INTERNAL_CALLER_CONTRACT, ECDSA_KEY, 1)))), + getAutoCreatedAccountBalance(ECDSA_KEY).hasTinyBars(changeFromSnapshot("autoCreatedSnapshot", 1))); } @HapiTest final Stream internalSendToNonExistingMirrorAddressDoesNotLazyCreateIt() { - return defaultHapiSpec("internalSendToNonExistingMirrorAddressDoesNotLazyCreateIt") - .given( - uploadInitCode(INTERNAL_CALLER_CONTRACT), - contractCreate(INTERNAL_CALLER_CONTRACT).balance(ONE_HBAR)) - .when(contractCall( + return hapiTest( + uploadInitCode(INTERNAL_CALLER_CONTRACT), + contractCreate(INTERNAL_CALLER_CONTRACT).balance(ONE_HBAR), + contractCall( INTERNAL_CALLER_CONTRACT, SEND_TO_FUNCTION, mirrorAddrWith(FIRST_NONEXISTENT_CONTRACT_NUM + 5)) .gas(GAS_LIMIT_FOR_CALL * 4) - .via(INNER_TXN)) - .then(getAccountBalance("0.0." + (FIRST_NONEXISTENT_CONTRACT_NUM + 5)) + .via(INNER_TXN), + getAccountBalance("0.0." + (FIRST_NONEXISTENT_CONTRACT_NUM + 5)) .nodePayment(ONE_HBAR) .hasAnswerOnlyPrecheck(INVALID_ACCOUNT_ID)); } @@ -663,12 +632,11 @@ final Stream internalSendToExistingMirrorAddressResultsInSuccess() AtomicReference receiverId = new AtomicReference<>(); - return defaultHapiSpec("internalSendToExistingMirrorAddressResultsInSuccess") - .given( - cryptoCreate(RECEIVER).exposingCreatedIdTo(receiverId::set), - uploadInitCode(INTERNAL_CALLER_CONTRACT), - contractCreate(INTERNAL_CALLER_CONTRACT).balance(ONE_HBAR)) - .when(withOpContext((spec, op) -> allRunFor( + return hapiTest( + cryptoCreate(RECEIVER).exposingCreatedIdTo(receiverId::set), + uploadInitCode(INTERNAL_CALLER_CONTRACT), + contractCreate(INTERNAL_CALLER_CONTRACT).balance(ONE_HBAR), + withOpContext((spec, op) -> allRunFor( spec, balanceSnapshot("initialBalance", asAccountString(receiverId.get())), contractCall( @@ -676,12 +644,11 @@ final Stream internalSendToExistingMirrorAddressResultsInSuccess() SEND_TO_FUNCTION, mirrorAddrWith(receiverId.get().getAccountNum())) .gas(GAS_LIMIT_FOR_CALL * 4) - .via(INNER_TXN)))) - .then( - getTxnRecord(INNER_TXN) - .hasPriority(recordWith() - .transfers(including(tinyBarsFromTo(INTERNAL_CALLER_CONTRACT, RECEIVER, 1)))), - getAccountBalance(RECEIVER).hasTinyBars(changeFromSnapshot("initialBalance", 1))); + .via(INNER_TXN))), + getTxnRecord(INNER_TXN) + .hasPriority(recordWith() + .transfers(including(tinyBarsFromTo(INTERNAL_CALLER_CONTRACT, RECEIVER, 1)))), + getAccountBalance(RECEIVER).hasTinyBars(changeFromSnapshot("initialBalance", 1))); } @HapiTest @@ -689,19 +656,18 @@ final Stream internalSendToNonExistingNonMirrorAddressResultsInSucc AtomicReference nonExistingNonMirrorAddress = new AtomicReference<>(); - return defaultHapiSpec("internalSendToNonExistingNonMirrorAddressResultsInSuccess") - .given( - cryptoCreate(CUSTOM_PAYER).balance(ONE_HUNDRED_HBARS), - newKeyNamed(ECDSA_KEY).shape(SECP_256K1_SHAPE), - withOpContext((spec, op) -> { - final var ecdsaKey = spec.registry().getKey(ECDSA_KEY); - final var tmp = ecdsaKey.getECDSASecp256K1().toByteArray(); - final var addressBytes = recoverAddressFromPubKey(tmp); - nonExistingNonMirrorAddress.set(Bytes.of(addressBytes)); - }), - uploadInitCode(INTERNAL_CALLER_CONTRACT), - contractCreate(INTERNAL_CALLER_CONTRACT).balance(ONE_HBAR)) - .when(withOpContext((spec, op) -> allRunFor( + return hapiTest( + cryptoCreate(CUSTOM_PAYER).balance(ONE_HUNDRED_HBARS), + newKeyNamed(ECDSA_KEY).shape(SECP_256K1_SHAPE), + withOpContext((spec, op) -> { + final var ecdsaKey = spec.registry().getKey(ECDSA_KEY); + final var tmp = ecdsaKey.getECDSASecp256K1().toByteArray(); + final var addressBytes = recoverAddressFromPubKey(tmp); + nonExistingNonMirrorAddress.set(Bytes.of(addressBytes)); + }), + uploadInitCode(INTERNAL_CALLER_CONTRACT), + contractCreate(INTERNAL_CALLER_CONTRACT).balance(ONE_HBAR), + withOpContext((spec, op) -> allRunFor( spec, balanceSnapshot("contractBalance", INTERNAL_CALLER_CONTRACT), contractCall( @@ -711,26 +677,23 @@ final Stream internalSendToNonExistingNonMirrorAddressResultsInSucc .get() .toArray())) .gas(GAS_LIMIT_FOR_CALL * 4) - .payingWith(CUSTOM_PAYER)))) - .then( - getAccountBalance(INTERNAL_CALLER_CONTRACT) - .hasTinyBars(changeFromSnapshot("contractBalance", 0)), - sourcing(() -> getAliasedAccountInfo(ByteString.copyFrom( - nonExistingNonMirrorAddress.get().toArray())) - .hasCostAnswerPrecheck(INVALID_ACCOUNT_ID))); + .payingWith(CUSTOM_PAYER))), + getAccountBalance(INTERNAL_CALLER_CONTRACT).hasTinyBars(changeFromSnapshot("contractBalance", 0)), + sourcing(() -> getAliasedAccountInfo(ByteString.copyFrom( + nonExistingNonMirrorAddress.get().toArray())) + .hasCostAnswerPrecheck(INVALID_ACCOUNT_ID))); } @HapiTest final Stream internalSendToExistingNonMirrorAddressResultsInSuccess() { - return defaultHapiSpec("internalSendToExistingNonMirrorAddressResultsInSuccess") - .given( - newKeyNamed(ECDSA_KEY).shape(SECP_256K1_SHAPE), - cryptoTransfer(tinyBarsFromAccountToAlias(GENESIS, ECDSA_KEY, ONE_HUNDRED_HBARS)), - withOpContext((spec, opLog) -> updateSpecFor(spec, ECDSA_KEY)), - uploadInitCode(INTERNAL_CALLER_CONTRACT), - contractCreate(INTERNAL_CALLER_CONTRACT).balance(ONE_HBAR)) - .when(withOpContext((spec, op) -> { + return hapiTest( + newKeyNamed(ECDSA_KEY).shape(SECP_256K1_SHAPE), + cryptoTransfer(tinyBarsFromAccountToAlias(GENESIS, ECDSA_KEY, ONE_HUNDRED_HBARS)), + withOpContext((spec, opLog) -> updateSpecFor(spec, ECDSA_KEY)), + uploadInitCode(INTERNAL_CALLER_CONTRACT), + contractCreate(INTERNAL_CALLER_CONTRACT).balance(ONE_HBAR), + withOpContext((spec, op) -> { final var ecdsaKey = spec.registry().getKey(ECDSA_KEY); final var tmp = ecdsaKey.getECDSASecp256K1().toByteArray(); final var addressBytes = recoverAddressFromPubKey(tmp); @@ -740,27 +703,24 @@ final Stream internalSendToExistingNonMirrorAddressResultsInSuccess contractCall(INTERNAL_CALLER_CONTRACT, SEND_TO_FUNCTION, asHeadlongAddress(addressBytes)) .gas(GAS_LIMIT_FOR_CALL * 4) .via(INNER_TXN)); - })) - .then( - getTxnRecord(INNER_TXN) - .hasPriority(recordWith() - .transfers(including(tinyBarsFromTo(INTERNAL_CALLER_CONTRACT, ECDSA_KEY, 1)))), - getAutoCreatedAccountBalance(ECDSA_KEY) - .hasTinyBars(changeFromSnapshot("autoCreatedSnapshot", 1))); + }), + getTxnRecord(INNER_TXN) + .hasPriority(recordWith() + .transfers(including(tinyBarsFromTo(INTERNAL_CALLER_CONTRACT, ECDSA_KEY, 1)))), + getAutoCreatedAccountBalance(ECDSA_KEY).hasTinyBars(changeFromSnapshot("autoCreatedSnapshot", 1))); } @HapiTest final Stream internalCallWithValueToNonExistingMirrorAddressResultsInInvalidAliasKey() { - return defaultHapiSpec("internalCallWithValueToNonExistingMirrorAddressResultsInInvalidAliasKey") - .given( - uploadInitCode(INTERNAL_CALLER_CONTRACT), - contractCreate(INTERNAL_CALLER_CONTRACT).balance(ONE_HBAR)) - .when(contractCall( + return hapiTest( + uploadInitCode(INTERNAL_CALLER_CONTRACT), + contractCreate(INTERNAL_CALLER_CONTRACT).balance(ONE_HBAR), + contractCall( INTERNAL_CALLER_CONTRACT, CALL_WITH_VALUE_TO_FUNCTION, mirrorAddrWith(FIRST_NONEXISTENT_CONTRACT_NUM + 6)) - .gas(ENOUGH_GAS_LIMIT_FOR_CREATION)) - .then(getAccountBalance("0.0." + (FIRST_NONEXISTENT_CONTRACT_NUM + 6)) + .gas(ENOUGH_GAS_LIMIT_FOR_CREATION), + getAccountBalance("0.0." + (FIRST_NONEXISTENT_CONTRACT_NUM + 6)) .nodePayment(ONE_HBAR) .hasAnswerOnlyPrecheck(INVALID_ACCOUNT_ID)); } @@ -770,12 +730,11 @@ final Stream internalCallWithValueToExistingMirrorAddressResultsInS AtomicReference receiverId = new AtomicReference<>(); - return defaultHapiSpec("internalCallWithValueToExistingMirrorAddressResultsInSuccess") - .given( - cryptoCreate(RECEIVER).exposingCreatedIdTo(receiverId::set), - uploadInitCode(INTERNAL_CALLER_CONTRACT), - contractCreate(INTERNAL_CALLER_CONTRACT).balance(ONE_HBAR)) - .when(withOpContext((spec, op) -> allRunFor( + return hapiTest( + cryptoCreate(RECEIVER).exposingCreatedIdTo(receiverId::set), + uploadInitCode(INTERNAL_CALLER_CONTRACT), + contractCreate(INTERNAL_CALLER_CONTRACT).balance(ONE_HBAR), + withOpContext((spec, op) -> allRunFor( spec, balanceSnapshot("initialBalance", asAccountString(receiverId.get())), contractCall( @@ -783,12 +742,11 @@ final Stream internalCallWithValueToExistingMirrorAddressResultsInS CALL_WITH_VALUE_TO_FUNCTION, mirrorAddrWith(receiverId.get().getAccountNum())) .gas(GAS_LIMIT_FOR_CALL * 4) - .via(INNER_TXN)))) - .then( - getTxnRecord(INNER_TXN) - .hasPriority(recordWith() - .transfers(including(tinyBarsFromTo(INTERNAL_CALLER_CONTRACT, RECEIVER, 1)))), - getAccountBalance(RECEIVER).hasTinyBars(changeFromSnapshot("initialBalance", 1))); + .via(INNER_TXN))), + getTxnRecord(INNER_TXN) + .hasPriority(recordWith() + .transfers(including(tinyBarsFromTo(INTERNAL_CALLER_CONTRACT, RECEIVER, 1)))), + getAccountBalance(RECEIVER).hasTinyBars(changeFromSnapshot("initialBalance", 1))); } @HapiTest @@ -844,14 +802,13 @@ final Stream internalCallWithValueToExistingMirrorAddressResultsInS @HapiTest final Stream internalCallWithValueToExistingNonMirrorAddressResultsInSuccess() { - return defaultHapiSpec("internalCallWithValueToExistingNonMirrorAddressResultsInSuccess") - .given( - newKeyNamed(ECDSA_KEY).shape(SECP_256K1_SHAPE), - cryptoTransfer(tinyBarsFromAccountToAlias(GENESIS, ECDSA_KEY, ONE_HUNDRED_HBARS)), - withOpContext((spec, opLog) -> updateSpecFor(spec, ECDSA_KEY)), - uploadInitCode(INTERNAL_CALLER_CONTRACT), - contractCreate(INTERNAL_CALLER_CONTRACT).balance(ONE_HBAR)) - .when(withOpContext((spec, op) -> { + return hapiTest( + newKeyNamed(ECDSA_KEY).shape(SECP_256K1_SHAPE), + cryptoTransfer(tinyBarsFromAccountToAlias(GENESIS, ECDSA_KEY, ONE_HUNDRED_HBARS)), + withOpContext((spec, opLog) -> updateSpecFor(spec, ECDSA_KEY)), + uploadInitCode(INTERNAL_CALLER_CONTRACT), + contractCreate(INTERNAL_CALLER_CONTRACT).balance(ONE_HBAR), + withOpContext((spec, op) -> { final var ecdsaKey = spec.registry().getKey(ECDSA_KEY); final var tmp = ecdsaKey.getECDSASecp256K1().toByteArray(); final var addressBytes = recoverAddressFromPubKey(tmp); @@ -864,40 +821,37 @@ final Stream internalCallWithValueToExistingNonMirrorAddressResults asHeadlongAddress(addressBytes)) .gas(GAS_LIMIT_FOR_CALL * 4) .via(INNER_TXN)); - })) - .then( - getTxnRecord(INNER_TXN) - .hasPriority(recordWith() - .transfers(including(tinyBarsFromTo(INTERNAL_CALLER_CONTRACT, ECDSA_KEY, 1)))), - getAutoCreatedAccountBalance(ECDSA_KEY) - .hasTinyBars(changeFromSnapshot("autoCreatedSnapshot", 1))); + }), + getTxnRecord(INNER_TXN) + .hasPriority(recordWith() + .transfers(including(tinyBarsFromTo(INTERNAL_CALLER_CONTRACT, ECDSA_KEY, 1)))), + getAutoCreatedAccountBalance(ECDSA_KEY).hasTinyBars(changeFromSnapshot("autoCreatedSnapshot", 1))); } @HapiTest final Stream internalCallToDeletedContractReturnsSuccessfulNoop() { final AtomicLong calleeNum = new AtomicLong(); - return defaultHapiSpec("internalCallToDeletedContractReturnsSuccessfulNoop") - .given( - uploadInitCode(INTERNAL_CALLER_CONTRACT, INTERNAL_CALLEE_CONTRACT), - contractCreate(INTERNAL_CALLER_CONTRACT) - // Refusing ethereum create conversion, because we get INVALID_SIGNATURE upon - // tokenAssociate, - // since we have CONTRACT_ID key - .refusingEthConversion() - .balance(ONE_HBAR), - contractCreate(INTERNAL_CALLEE_CONTRACT) - // Refusing ethereum create conversion, because we get INVALID_SIGNATURE upon - // tokenAssociate, - // since we have CONTRACT_ID key - .refusingEthConversion() - .exposingNumTo(calleeNum::set), - contractDelete(INTERNAL_CALLEE_CONTRACT)) - .when(withOpContext((spec, ignored) -> allRunFor( + return hapiTest( + uploadInitCode(INTERNAL_CALLER_CONTRACT, INTERNAL_CALLEE_CONTRACT), + contractCreate(INTERNAL_CALLER_CONTRACT) + // Refusing ethereum create conversion, because we get INVALID_SIGNATURE upon + // tokenAssociate, + // since we have CONTRACT_ID key + .refusingEthConversion() + .balance(ONE_HBAR), + contractCreate(INTERNAL_CALLEE_CONTRACT) + // Refusing ethereum create conversion, because we get INVALID_SIGNATURE upon + // tokenAssociate, + // since we have CONTRACT_ID key + .refusingEthConversion() + .exposingNumTo(calleeNum::set), + contractDelete(INTERNAL_CALLEE_CONTRACT), + withOpContext((spec, ignored) -> allRunFor( spec, contractCall(INTERNAL_CALLER_CONTRACT, CALL_EXTERNAL_FUNCTION, mirrorAddrWith(calleeNum.get())) .gas(50_000L) - .via(INNER_TXN)))) - .then(withOpContext((spec, opLog) -> { + .via(INNER_TXN))), + withOpContext((spec, opLog) -> { final var lookup = getTxnRecord(INNER_TXN); allRunFor(spec, lookup); final var result = @@ -909,38 +863,35 @@ final Stream internalCallToDeletedContractReturnsSuccessfulNoop() { @HapiTest final Stream callingDestructedContractReturnsStatusSuccess() { final AtomicReference accountIDAtomicReference = new AtomicReference<>(); - return defaultHapiSpec("callingDestructedContractReturnsStatusSuccess") - .given( - cryptoCreate(BENEFICIARY).exposingCreatedIdTo(accountIDAtomicReference::set), - uploadInitCode(SIMPLE_UPDATE_CONTRACT)) - .when( - contractCreate(SIMPLE_UPDATE_CONTRACT).gas(300_000L), - contractCall(SIMPLE_UPDATE_CONTRACT, "set", BigInteger.valueOf(5), BigInteger.valueOf(42)) - .gas(300_000L), - sourcing(() -> contractCall( - SIMPLE_UPDATE_CONTRACT, - "del", - asHeadlongAddress(asAddress(accountIDAtomicReference.get()))) - .gas(1_000_000L))) - .then(contractCall(SIMPLE_UPDATE_CONTRACT, "set", BigInteger.valueOf(15), BigInteger.valueOf(434)) + return hapiTest( + cryptoCreate(BENEFICIARY).exposingCreatedIdTo(accountIDAtomicReference::set), + uploadInitCode(SIMPLE_UPDATE_CONTRACT), + contractCreate(SIMPLE_UPDATE_CONTRACT).gas(300_000L), + contractCall(SIMPLE_UPDATE_CONTRACT, "set", BigInteger.valueOf(5), BigInteger.valueOf(42)) + .gas(300_000L), + sourcing(() -> contractCall( + SIMPLE_UPDATE_CONTRACT, + "del", + asHeadlongAddress(asAddress(accountIDAtomicReference.get()))) + .gas(1_000_000L)), + contractCall(SIMPLE_UPDATE_CONTRACT, "set", BigInteger.valueOf(15), BigInteger.valueOf(434)) .gas(350_000L) .hasKnownStatus(SUCCESS)); } @HapiTest final Stream internalStaticCallNonExistingMirrorAddressResultsInSuccess() { - return defaultHapiSpec("internalStaticCallNonExistingMirrorAddressResultsInSuccess") - .given( - uploadInitCode(INTERNAL_CALLER_CONTRACT), - contractCreate(INTERNAL_CALLER_CONTRACT).balance(ONE_HBAR)) - .when(contractCall( + return hapiTest( + uploadInitCode(INTERNAL_CALLER_CONTRACT), + contractCreate(INTERNAL_CALLER_CONTRACT).balance(ONE_HBAR), + contractCall( INTERNAL_CALLER_CONTRACT, STATIC_CALL_EXTERNAL_FUNCTION, mirrorAddrWith(FIRST_NONEXISTENT_CONTRACT_NUM + 9)) .gas(GAS_LIMIT_FOR_CALL) .via(INNER_TXN) - .hasKnownStatus(SUCCESS)) - .then(getTxnRecord(INNER_TXN) + .hasKnownStatus(SUCCESS), + getTxnRecord(INNER_TXN) .logged() .hasPriority( recordWith().contractCallResult(resultWith().contractCallResult(bigIntResult(0))))); @@ -949,12 +900,11 @@ final Stream internalStaticCallNonExistingMirrorAddressResultsInSuc @HapiTest final Stream internalStaticCallExistingMirrorAddressResultsInSuccess() { AtomicReference receiverId = new AtomicReference<>(); - return defaultHapiSpec("internalStaticCallExistingMirrorAddressResultsInSuccess") - .given( - cryptoCreate(RECEIVER).exposingCreatedIdTo(receiverId::set), - uploadInitCode(INTERNAL_CALLER_CONTRACT), - contractCreate(INTERNAL_CALLER_CONTRACT).balance(ONE_HBAR)) - .when(withOpContext((spec, op) -> allRunFor( + return hapiTest( + cryptoCreate(RECEIVER).exposingCreatedIdTo(receiverId::set), + uploadInitCode(INTERNAL_CALLER_CONTRACT), + contractCreate(INTERNAL_CALLER_CONTRACT).balance(ONE_HBAR), + withOpContext((spec, op) -> allRunFor( spec, balanceSnapshot("initialBalance", asAccountString(receiverId.get())), contractCall( @@ -962,30 +912,28 @@ final Stream internalStaticCallExistingMirrorAddressResultsInSucces STATIC_CALL_EXTERNAL_FUNCTION, mirrorAddrWith(receiverId.get().getAccountNum())) .gas(GAS_LIMIT_FOR_CALL) - .via(INNER_TXN)))) - .then( - getTxnRecord(INNER_TXN) - .hasPriority(recordWith() - .contractCallResult(resultWith().contractCallResult(bigIntResult(0)))), - getAccountBalance(RECEIVER).hasTinyBars(changeFromSnapshot("initialBalance", 0))); + .via(INNER_TXN))), + getTxnRecord(INNER_TXN) + .hasPriority( + recordWith().contractCallResult(resultWith().contractCallResult(bigIntResult(0)))), + getAccountBalance(RECEIVER).hasTinyBars(changeFromSnapshot("initialBalance", 0))); } @HapiTest final Stream internalStaticCallNonExistingNonMirrorAddressResultsInSuccess() { AtomicReference nonExistingNonMirrorAddress = new AtomicReference<>(); - return defaultHapiSpec("internalStaticCallNonExistingNonMirrorAddressResultsInSuccess") - .given( - cryptoCreate(CUSTOM_PAYER).balance(ONE_HUNDRED_HBARS), - newKeyNamed(ECDSA_KEY).shape(SECP_256K1_SHAPE), - withOpContext((spec, op) -> { - final var ecdsaKey = spec.registry().getKey(ECDSA_KEY); - final var tmp = ecdsaKey.getECDSASecp256K1().toByteArray(); - final var addressBytes = recoverAddressFromPubKey(tmp); - nonExistingNonMirrorAddress.set(Bytes.of(addressBytes)); - }), - uploadInitCode(INTERNAL_CALLER_CONTRACT), - contractCreate(INTERNAL_CALLER_CONTRACT).balance(ONE_HBAR)) - .when(withOpContext((spec, op) -> allRunFor( + return hapiTest( + cryptoCreate(CUSTOM_PAYER).balance(ONE_HUNDRED_HBARS), + newKeyNamed(ECDSA_KEY).shape(SECP_256K1_SHAPE), + withOpContext((spec, op) -> { + final var ecdsaKey = spec.registry().getKey(ECDSA_KEY); + final var tmp = ecdsaKey.getECDSASecp256K1().toByteArray(); + final var addressBytes = recoverAddressFromPubKey(tmp); + nonExistingNonMirrorAddress.set(Bytes.of(addressBytes)); + }), + uploadInitCode(INTERNAL_CALLER_CONTRACT), + contractCreate(INTERNAL_CALLER_CONTRACT).balance(ONE_HBAR), + withOpContext((spec, op) -> allRunFor( spec, balanceSnapshot("contractBalance", INTERNAL_CALLER_CONTRACT), contractCall( @@ -996,25 +944,22 @@ final Stream internalStaticCallNonExistingNonMirrorAddressResultsIn .toArray())) .gas(GAS_LIMIT_FOR_CALL) .payingWith(CUSTOM_PAYER) - .via(INNER_TXN)))) - .then( - getTxnRecord(INNER_TXN) - .hasPriority(recordWith() - .contractCallResult(resultWith().contractCallResult(bigIntResult(0)))), - getAccountBalance(INTERNAL_CALLER_CONTRACT) - .hasTinyBars(changeFromSnapshot("contractBalance", 0))); + .via(INNER_TXN))), + getTxnRecord(INNER_TXN) + .hasPriority( + recordWith().contractCallResult(resultWith().contractCallResult(bigIntResult(0)))), + getAccountBalance(INTERNAL_CALLER_CONTRACT).hasTinyBars(changeFromSnapshot("contractBalance", 0))); } @HapiTest final Stream internalStaticCallExistingNonMirrorAddressResultsInSuccess() { - return defaultHapiSpec("internalStaticCallExistingNonMirrorAddressResultsInSuccess") - .given( - newKeyNamed(ECDSA_KEY).shape(SECP_256K1_SHAPE), - cryptoTransfer(tinyBarsFromAccountToAlias(GENESIS, ECDSA_KEY, ONE_HUNDRED_HBARS)), - withOpContext((spec, opLog) -> updateSpecFor(spec, ECDSA_KEY)), - uploadInitCode(INTERNAL_CALLER_CONTRACT), - contractCreate(INTERNAL_CALLER_CONTRACT).balance(ONE_HBAR)) - .when(withOpContext((spec, op) -> { + return hapiTest( + newKeyNamed(ECDSA_KEY).shape(SECP_256K1_SHAPE), + cryptoTransfer(tinyBarsFromAccountToAlias(GENESIS, ECDSA_KEY, ONE_HUNDRED_HBARS)), + withOpContext((spec, opLog) -> updateSpecFor(spec, ECDSA_KEY)), + uploadInitCode(INTERNAL_CALLER_CONTRACT), + contractCreate(INTERNAL_CALLER_CONTRACT).balance(ONE_HBAR), + withOpContext((spec, op) -> { final var ecdsaKey = spec.registry().getKey(ECDSA_KEY); final var tmp = ecdsaKey.getECDSASecp256K1().toByteArray(); final var addressBytes = recoverAddressFromPubKey(tmp); @@ -1027,28 +972,26 @@ final Stream internalStaticCallExistingNonMirrorAddressResultsInSuc asHeadlongAddress(addressBytes)) .gas(GAS_LIMIT_FOR_CALL) .via(INNER_TXN)); - })) - .then( - getTxnRecord(INNER_TXN) - .hasPriority(recordWith() - .contractCallResult(resultWith().contractCallResult(bigIntResult(0)))), - getAutoCreatedAccountBalance(ECDSA_KEY).hasTinyBars(changeFromSnapshot("targetSnapshot", 0))); + }), + getTxnRecord(INNER_TXN) + .hasPriority( + recordWith().contractCallResult(resultWith().contractCallResult(bigIntResult(0)))), + getAutoCreatedAccountBalance(ECDSA_KEY).hasTinyBars(changeFromSnapshot("targetSnapshot", 0))); } @HapiTest final Stream internalDelegateCallNonExistingMirrorAddressResultsInSuccess() { - return defaultHapiSpec("internalDelegateCallNonExistingMirrorAddressResultsInSuccess") - .given( - uploadInitCode(INTERNAL_CALLER_CONTRACT), - contractCreate(INTERNAL_CALLER_CONTRACT).balance(ONE_HBAR)) - .when(contractCall( + return hapiTest( + uploadInitCode(INTERNAL_CALLER_CONTRACT), + contractCreate(INTERNAL_CALLER_CONTRACT).balance(ONE_HBAR), + contractCall( INTERNAL_CALLER_CONTRACT, DELEGATE_CALL_EXTERNAL_FUNCTION, mirrorAddrWith(FIRST_NONEXISTENT_CONTRACT_NUM + 10)) .gas(GAS_LIMIT_FOR_CALL) .via(INNER_TXN) - .hasKnownStatus(SUCCESS)) - .then(getTxnRecord(INNER_TXN) + .hasKnownStatus(SUCCESS), + getTxnRecord(INNER_TXN) .logged() .hasPriority( recordWith().contractCallResult(resultWith().contractCallResult(bigIntResult(0))))); @@ -1057,12 +1000,11 @@ final Stream internalDelegateCallNonExistingMirrorAddressResultsInS @HapiTest final Stream internalDelegateCallExistingMirrorAddressResultsInSuccess() { AtomicReference receiverId = new AtomicReference<>(); - return defaultHapiSpec("internalDelegateCallExistingMirrorAddressResultsInSuccess") - .given( - cryptoCreate(RECEIVER).exposingCreatedIdTo(receiverId::set), - uploadInitCode(INTERNAL_CALLER_CONTRACT), - contractCreate(INTERNAL_CALLER_CONTRACT).balance(ONE_HBAR)) - .when(withOpContext((spec, op) -> allRunFor( + return hapiTest( + cryptoCreate(RECEIVER).exposingCreatedIdTo(receiverId::set), + uploadInitCode(INTERNAL_CALLER_CONTRACT), + contractCreate(INTERNAL_CALLER_CONTRACT).balance(ONE_HBAR), + withOpContext((spec, op) -> allRunFor( spec, balanceSnapshot("initialBalance", asAccountString(receiverId.get())), contractCall( @@ -1070,30 +1012,28 @@ final Stream internalDelegateCallExistingMirrorAddressResultsInSucc DELEGATE_CALL_EXTERNAL_FUNCTION, mirrorAddrWith(receiverId.get().getAccountNum())) .gas(GAS_LIMIT_FOR_CALL) - .via(INNER_TXN)))) - .then( - getTxnRecord(INNER_TXN) - .hasPriority(recordWith() - .contractCallResult(resultWith().contractCallResult(bigIntResult(0)))), - getAccountBalance(RECEIVER).hasTinyBars(changeFromSnapshot("initialBalance", 0))); + .via(INNER_TXN))), + getTxnRecord(INNER_TXN) + .hasPriority( + recordWith().contractCallResult(resultWith().contractCallResult(bigIntResult(0)))), + getAccountBalance(RECEIVER).hasTinyBars(changeFromSnapshot("initialBalance", 0))); } @HapiTest final Stream internalDelegateCallNonExistingNonMirrorAddressResultsInSuccess() { AtomicReference nonExistingNonMirrorAddress = new AtomicReference<>(); - return defaultHapiSpec("internalDelegateCallNonExistingNonMirrorAddressResultsInSuccess") - .given( - cryptoCreate(CUSTOM_PAYER).balance(ONE_HUNDRED_HBARS), - newKeyNamed(ECDSA_KEY).shape(SECP_256K1_SHAPE), - withOpContext((spec, op) -> { - final var ecdsaKey = spec.registry().getKey(ECDSA_KEY); - final var tmp = ecdsaKey.getECDSASecp256K1().toByteArray(); - final var addressBytes = recoverAddressFromPubKey(tmp); - nonExistingNonMirrorAddress.set(Bytes.of(addressBytes)); - }), - uploadInitCode(INTERNAL_CALLER_CONTRACT), - contractCreate(INTERNAL_CALLER_CONTRACT).balance(ONE_HBAR)) - .when(withOpContext((spec, op) -> allRunFor( + return hapiTest( + cryptoCreate(CUSTOM_PAYER).balance(ONE_HUNDRED_HBARS), + newKeyNamed(ECDSA_KEY).shape(SECP_256K1_SHAPE), + withOpContext((spec, op) -> { + final var ecdsaKey = spec.registry().getKey(ECDSA_KEY); + final var tmp = ecdsaKey.getECDSASecp256K1().toByteArray(); + final var addressBytes = recoverAddressFromPubKey(tmp); + nonExistingNonMirrorAddress.set(Bytes.of(addressBytes)); + }), + uploadInitCode(INTERNAL_CALLER_CONTRACT), + contractCreate(INTERNAL_CALLER_CONTRACT).balance(ONE_HBAR), + withOpContext((spec, op) -> allRunFor( spec, balanceSnapshot("contractBalance", INTERNAL_CALLER_CONTRACT), contractCall( @@ -1104,25 +1044,22 @@ final Stream internalDelegateCallNonExistingNonMirrorAddressResults .toArray())) .gas(GAS_LIMIT_FOR_CALL) .payingWith(CUSTOM_PAYER) - .via(INNER_TXN)))) - .then( - getTxnRecord(INNER_TXN) - .hasPriority(recordWith() - .contractCallResult(resultWith().contractCallResult(bigIntResult(0)))), - getAccountBalance(INTERNAL_CALLER_CONTRACT) - .hasTinyBars(changeFromSnapshot("contractBalance", 0))); + .via(INNER_TXN))), + getTxnRecord(INNER_TXN) + .hasPriority( + recordWith().contractCallResult(resultWith().contractCallResult(bigIntResult(0)))), + getAccountBalance(INTERNAL_CALLER_CONTRACT).hasTinyBars(changeFromSnapshot("contractBalance", 0))); } @HapiTest final Stream internalDelegateCallExistingNonMirrorAddressResultsInSuccess() { - return defaultHapiSpec("internalDelegateCallExistingNonMirrorAddressResultsInSuccess") - .given( - newKeyNamed(ECDSA_KEY).shape(SECP_256K1_SHAPE), - cryptoTransfer(tinyBarsFromAccountToAlias(GENESIS, ECDSA_KEY, ONE_HUNDRED_HBARS)), - withOpContext((spec, opLog) -> updateSpecFor(spec, ECDSA_KEY)), - uploadInitCode(INTERNAL_CALLER_CONTRACT), - contractCreate(INTERNAL_CALLER_CONTRACT).balance(ONE_HBAR)) - .when(withOpContext((spec, op) -> { + return hapiTest( + newKeyNamed(ECDSA_KEY).shape(SECP_256K1_SHAPE), + cryptoTransfer(tinyBarsFromAccountToAlias(GENESIS, ECDSA_KEY, ONE_HUNDRED_HBARS)), + withOpContext((spec, opLog) -> updateSpecFor(spec, ECDSA_KEY)), + uploadInitCode(INTERNAL_CALLER_CONTRACT), + contractCreate(INTERNAL_CALLER_CONTRACT).balance(ONE_HBAR), + withOpContext((spec, op) -> { final var ecdsaKey = spec.registry().getKey(ECDSA_KEY); final var tmp = ecdsaKey.getECDSASecp256K1().toByteArray(); final var addressBytes = recoverAddressFromPubKey(tmp); @@ -1135,24 +1072,22 @@ final Stream internalDelegateCallExistingNonMirrorAddressResultsInS asHeadlongAddress(addressBytes)) .gas(GAS_LIMIT_FOR_CALL) .via(INNER_TXN)); - })) - .then( - getTxnRecord(INNER_TXN) - .hasPriority(recordWith() - .contractCallResult(resultWith().contractCallResult(bigIntResult(0)))), - getAutoCreatedAccountBalance(ECDSA_KEY).hasTinyBars(changeFromSnapshot("targetSnapshot", 0))); + }), + getTxnRecord(INNER_TXN) + .hasPriority( + recordWith().contractCallResult(resultWith().contractCallResult(bigIntResult(0)))), + getAutoCreatedAccountBalance(ECDSA_KEY).hasTinyBars(changeFromSnapshot("targetSnapshot", 0))); } @HapiTest final Stream internalCallWithValueToAccountWithReceiverSigRequiredTrue() { AtomicReference receiverId = new AtomicReference<>(); - return defaultHapiSpec("internalCallWithValueToAccountWithReceiverSigRequiredTrue") - .given( - cryptoCreate(RECEIVER).receiverSigRequired(true).exposingCreatedIdTo(receiverId::set), - uploadInitCode(INTERNAL_CALLER_CONTRACT), - contractCreate(INTERNAL_CALLER_CONTRACT).balance(ONE_HBAR)) - .when(withOpContext((spec, op) -> allRunFor( + return hapiTest( + cryptoCreate(RECEIVER).receiverSigRequired(true).exposingCreatedIdTo(receiverId::set), + uploadInitCode(INTERNAL_CALLER_CONTRACT), + contractCreate(INTERNAL_CALLER_CONTRACT).balance(ONE_HBAR), + withOpContext((spec, op) -> allRunFor( spec, balanceSnapshot("initialBalance", INTERNAL_CALLER_CONTRACT), contractCall( @@ -1161,11 +1096,9 @@ final Stream internalCallWithValueToAccountWithReceiverSigRequiredT mirrorAddrWith(receiverId.get().getAccountNum())) .gas(GAS_LIMIT_FOR_CALL * 4) .via(INNER_TXN) - .hasKnownStatus(INVALID_SIGNATURE)))) - .then( - getTxnRecord(INNER_TXN).hasPriority(recordWith().status(INVALID_SIGNATURE)), - getAccountBalance(INTERNAL_CALLER_CONTRACT) - .hasTinyBars(changeFromSnapshot("initialBalance", 0))); + .hasKnownStatus(INVALID_SIGNATURE))), + getTxnRecord(INNER_TXN).hasPriority(recordWith().status(INVALID_SIGNATURE)), + getAccountBalance(INTERNAL_CALLER_CONTRACT).hasTinyBars(changeFromSnapshot("initialBalance", 0))); } @HapiTest @@ -1173,24 +1106,20 @@ final Stream internalCallToSystemAccount564ResultsInSuccessNoop() { AtomicReference targetId = new AtomicReference<>(); targetId.set(AccountID.newBuilder().setAccountNum(564L).build()); - return defaultHapiSpec("internalCallToSystemAccount564ResultsInSuccessNoop") - .given( - uploadInitCode(INTERNAL_CALLER_CONTRACT), - contractCreate(INTERNAL_CALLER_CONTRACT).balance(ONE_HBAR)) - .when( - balanceSnapshot("initialBalance", INTERNAL_CALLER_CONTRACT), - withOpContext((spec, op) -> allRunFor( - spec, - contractCall( - INTERNAL_CALLER_CONTRACT, - CALL_EXTERNAL_FUNCTION, - mirrorAddrWith(targetId.get().getAccountNum())) - .gas(GAS_LIMIT_FOR_CALL * 4) - .via(INNER_TXN)))) - .then( - getTxnRecord(INNER_TXN).hasPriority(recordWith().status(SUCCESS)), - getAccountBalance(INTERNAL_CALLER_CONTRACT) - .hasTinyBars(changeFromSnapshot("initialBalance", 0))); + return hapiTest( + uploadInitCode(INTERNAL_CALLER_CONTRACT), + contractCreate(INTERNAL_CALLER_CONTRACT).balance(ONE_HBAR), + balanceSnapshot("initialBalance", INTERNAL_CALLER_CONTRACT), + withOpContext((spec, op) -> allRunFor( + spec, + contractCall( + INTERNAL_CALLER_CONTRACT, + CALL_EXTERNAL_FUNCTION, + mirrorAddrWith(targetId.get().getAccountNum())) + .gas(GAS_LIMIT_FOR_CALL * 4) + .via(INNER_TXN))), + getTxnRecord(INNER_TXN).hasPriority(recordWith().status(SUCCESS)), + getAccountBalance(INTERNAL_CALLER_CONTRACT).hasTinyBars(changeFromSnapshot("initialBalance", 0))); } @HapiTest @@ -1239,31 +1168,26 @@ final Stream internalCallToEthereumPrecompile0x2ResultsInSuccess() AtomicReference targetId = new AtomicReference<>(); targetId.set(AccountID.newBuilder().setAccountNum(2L).build()); - return defaultHapiSpec("internalCallToEthereumPrecompile0x2ResultsInSuccess") - .given( - uploadInitCode(INTERNAL_CALLER_CONTRACT), - contractCreate(INTERNAL_CALLER_CONTRACT).balance(ONE_HBAR)) - .when( - balanceSnapshot("initialBalance", INTERNAL_CALLER_CONTRACT), - withOpContext((spec, op) -> allRunFor( - spec, - contractCall( - INTERNAL_CALLER_CONTRACT, - CALL_EXTERNAL_FUNCTION, - mirrorAddrWith(targetId.get().getAccountNum())) - .gas(GAS_LIMIT_FOR_CALL * 4) - .via(INNER_TXN)))) - .then( - withOpContext((spec, opLog) -> { - final var lookup = getTxnRecord(INNER_TXN); - allRunFor(spec, lookup); - final var result = lookup.getResponseRecord() - .getContractCallResult() - .getContractCallResult(); - assertNotEquals(ByteString.copyFrom(new byte[32]), result); - }), - getAccountBalance(INTERNAL_CALLER_CONTRACT) - .hasTinyBars(changeFromSnapshot("initialBalance", 0))); + return hapiTest( + uploadInitCode(INTERNAL_CALLER_CONTRACT), + contractCreate(INTERNAL_CALLER_CONTRACT).balance(ONE_HBAR), + balanceSnapshot("initialBalance", INTERNAL_CALLER_CONTRACT), + withOpContext((spec, op) -> allRunFor( + spec, + contractCall( + INTERNAL_CALLER_CONTRACT, + CALL_EXTERNAL_FUNCTION, + mirrorAddrWith(targetId.get().getAccountNum())) + .gas(GAS_LIMIT_FOR_CALL * 4) + .via(INNER_TXN))), + withOpContext((spec, opLog) -> { + final var lookup = getTxnRecord(INNER_TXN); + allRunFor(spec, lookup); + final var result = + lookup.getResponseRecord().getContractCallResult().getContractCallResult(); + assertNotEquals(ByteString.copyFrom(new byte[32]), result); + }), + getAccountBalance(INTERNAL_CALLER_CONTRACT).hasTinyBars(changeFromSnapshot("initialBalance", 0))); } @HapiTest @@ -1271,22 +1195,20 @@ final Stream internalCallWithValueToEthereumPrecompile0x2ResultsInR AtomicReference targetId = new AtomicReference<>(); targetId.set(AccountID.newBuilder().setAccountNum(2L).build()); - return defaultHapiSpec("internalCallWithValueToEthereumPrecompile0x2ResultsInRevert") - .given( - uploadInitCode(INTERNAL_CALLER_CONTRACT), - contractCreate(INTERNAL_CALLER_CONTRACT).balance(ONE_HBAR)) - .when( - balanceSnapshot("initialBalance", INTERNAL_CALLER_CONTRACT), - withOpContext((spec, op) -> allRunFor( - spec, - contractCall( - INTERNAL_CALLER_CONTRACT, - CALL_WITH_VALUE_TO_FUNCTION, - mirrorAddrWith(targetId.get().getAccountNum())) - .gas(GAS_LIMIT_FOR_CALL * 4) - .via(INNER_TXN) - .hasKnownStatus(INVALID_CONTRACT_ID)))) - .then(getAccountBalance(INTERNAL_CALLER_CONTRACT).hasTinyBars(changeFromSnapshot("initialBalance", 0))); + return hapiTest( + uploadInitCode(INTERNAL_CALLER_CONTRACT), + contractCreate(INTERNAL_CALLER_CONTRACT).balance(ONE_HBAR), + balanceSnapshot("initialBalance", INTERNAL_CALLER_CONTRACT), + withOpContext((spec, op) -> allRunFor( + spec, + contractCall( + INTERNAL_CALLER_CONTRACT, + CALL_WITH_VALUE_TO_FUNCTION, + mirrorAddrWith(targetId.get().getAccountNum())) + .gas(GAS_LIMIT_FOR_CALL * 4) + .via(INNER_TXN) + .hasKnownStatus(INVALID_CONTRACT_ID))), + getAccountBalance(INTERNAL_CALLER_CONTRACT).hasTinyBars(changeFromSnapshot("initialBalance", 0))); } @HapiTest @@ -1294,24 +1216,20 @@ final Stream internalCallToNonExistingSystemAccount852ResultsInSucc AtomicReference targetId = new AtomicReference<>(); targetId.set(AccountID.newBuilder().setAccountNum(852L).build()); - return defaultHapiSpec("internalCallToNonExistingSystemAccount852ResultsInSuccessNoop") - .given( - uploadInitCode(INTERNAL_CALLER_CONTRACT), - contractCreate(INTERNAL_CALLER_CONTRACT).balance(ONE_HBAR)) - .when( - balanceSnapshot("initialBalance", INTERNAL_CALLER_CONTRACT), - withOpContext((spec, op) -> allRunFor( - spec, - contractCall( - INTERNAL_CALLER_CONTRACT, - CALL_EXTERNAL_FUNCTION, - mirrorAddrWith(targetId.get().getAccountNum())) - .gas(GAS_LIMIT_FOR_CALL * 4) - .via(INNER_TXN)))) - .then( - getTxnRecord(INNER_TXN).hasPriority(recordWith().status(SUCCESS)), - getAccountBalance(INTERNAL_CALLER_CONTRACT) - .hasTinyBars(changeFromSnapshot("initialBalance", 0))); + return hapiTest( + uploadInitCode(INTERNAL_CALLER_CONTRACT), + contractCreate(INTERNAL_CALLER_CONTRACT).balance(ONE_HBAR), + balanceSnapshot("initialBalance", INTERNAL_CALLER_CONTRACT), + withOpContext((spec, op) -> allRunFor( + spec, + contractCall( + INTERNAL_CALLER_CONTRACT, + CALL_EXTERNAL_FUNCTION, + mirrorAddrWith(targetId.get().getAccountNum())) + .gas(GAS_LIMIT_FOR_CALL * 4) + .via(INNER_TXN))), + getTxnRecord(INNER_TXN).hasPriority(recordWith().status(SUCCESS)), + getAccountBalance(INTERNAL_CALLER_CONTRACT).hasTinyBars(changeFromSnapshot("initialBalance", 0))); } @HapiTest @@ -1320,23 +1238,19 @@ final Stream internalCallWithValueToNonExistingSystemAccount852Resu final var systemAccountNum = 852L; targetId.set(AccountID.newBuilder().setAccountNum(systemAccountNum).build()); - return defaultHapiSpec("internalCallWithValueToNonExistingSystemAccount852ResultsInInvalidAliasKey") - .given( - uploadInitCode(INTERNAL_CALLER_CONTRACT), - contractCreate(INTERNAL_CALLER_CONTRACT).balance(ONE_HBAR)) - .when( - balanceSnapshot("initialBalance", INTERNAL_CALLER_CONTRACT), - withOpContext((spec, op) -> allRunFor( - spec, - contractCall( - INTERNAL_CALLER_CONTRACT, - CALL_WITH_VALUE_TO_FUNCTION, - mirrorAddrWith(targetId.get().getAccountNum())) - .gas(GAS_LIMIT_FOR_CALL * 4)))) - .then( - getAccountBalance(INTERNAL_CALLER_CONTRACT) - .hasTinyBars(changeFromSnapshot("initialBalance", 0)), - getAccountBalance("0.0." + systemAccountNum).hasAnswerOnlyPrecheck(INVALID_ACCOUNT_ID)); + return hapiTest( + uploadInitCode(INTERNAL_CALLER_CONTRACT), + contractCreate(INTERNAL_CALLER_CONTRACT).balance(ONE_HBAR), + balanceSnapshot("initialBalance", INTERNAL_CALLER_CONTRACT), + withOpContext((spec, op) -> allRunFor( + spec, + contractCall( + INTERNAL_CALLER_CONTRACT, + CALL_WITH_VALUE_TO_FUNCTION, + mirrorAddrWith(targetId.get().getAccountNum())) + .gas(GAS_LIMIT_FOR_CALL * 4))), + getAccountBalance(INTERNAL_CALLER_CONTRACT).hasTinyBars(changeFromSnapshot("initialBalance", 0)), + getAccountBalance("0.0." + systemAccountNum).hasAnswerOnlyPrecheck(INVALID_ACCOUNT_ID)); } @HapiTest @@ -1344,22 +1258,20 @@ final Stream internalCallWithValueToSystemAccount564ResultsInSucces AtomicReference targetId = new AtomicReference<>(); targetId.set(AccountID.newBuilder().setAccountNum(564L).build()); - return defaultHapiSpec("internalCallWithValueToSystemAccount564ResultsInSuccessNoopNoTransfer") - .given( - uploadInitCode(INTERNAL_CALLER_CONTRACT), - contractCreate(INTERNAL_CALLER_CONTRACT).balance(ONE_HBAR)) - .when( - balanceSnapshot("initialBalance", INTERNAL_CALLER_CONTRACT), - withOpContext((spec, op) -> allRunFor( - spec, - contractCall( - INTERNAL_CALLER_CONTRACT, - CALL_WITH_VALUE_TO_FUNCTION, - mirrorAddrWith(targetId.get().getAccountNum())) - .gas(GAS_LIMIT_FOR_CALL * 4) - .via(INNER_TXN) - .hasKnownStatus(INVALID_CONTRACT_ID)))) - .then(getAccountBalance(INTERNAL_CALLER_CONTRACT).hasTinyBars(changeFromSnapshot("initialBalance", 0))); + return hapiTest( + uploadInitCode(INTERNAL_CALLER_CONTRACT), + contractCreate(INTERNAL_CALLER_CONTRACT).balance(ONE_HBAR), + balanceSnapshot("initialBalance", INTERNAL_CALLER_CONTRACT), + withOpContext((spec, op) -> allRunFor( + spec, + contractCall( + INTERNAL_CALLER_CONTRACT, + CALL_WITH_VALUE_TO_FUNCTION, + mirrorAddrWith(targetId.get().getAccountNum())) + .gas(GAS_LIMIT_FOR_CALL * 4) + .via(INNER_TXN) + .hasKnownStatus(INVALID_CONTRACT_ID))), + getAccountBalance(INTERNAL_CALLER_CONTRACT).hasTinyBars(changeFromSnapshot("initialBalance", 0))); } @HapiTest @@ -1367,24 +1279,20 @@ final Stream internalCallWithValueToExistingSystemAccount800Results AtomicReference targetId = new AtomicReference<>(); targetId.set(AccountID.newBuilder().setAccountNum(800L).build()); - return defaultHapiSpec("internalCallWithValueToExistingSystemAccount800ResultsInSuccessfulTransfer") - .given( - uploadInitCode(INTERNAL_CALLER_CONTRACT), - contractCreate(INTERNAL_CALLER_CONTRACT).balance(ONE_HBAR)) - .when( - balanceSnapshot("initialBalance", INTERNAL_CALLER_CONTRACT), - withOpContext((spec, op) -> allRunFor( - spec, - contractCall( - INTERNAL_CALLER_CONTRACT, - CALL_WITH_VALUE_TO_FUNCTION, - mirrorAddrWith(targetId.get().getAccountNum())) - .gas(GAS_LIMIT_FOR_CALL * 4) - .via(INNER_TXN)))) - .then( - getTxnRecord(INNER_TXN).hasPriority(recordWith().status(SUCCESS)), - getAccountBalance(INTERNAL_CALLER_CONTRACT) - .hasTinyBars(changeFromSnapshot("initialBalance", -1))); + return hapiTest( + uploadInitCode(INTERNAL_CALLER_CONTRACT), + contractCreate(INTERNAL_CALLER_CONTRACT).balance(ONE_HBAR), + balanceSnapshot("initialBalance", INTERNAL_CALLER_CONTRACT), + withOpContext((spec, op) -> allRunFor( + spec, + contractCall( + INTERNAL_CALLER_CONTRACT, + CALL_WITH_VALUE_TO_FUNCTION, + mirrorAddrWith(targetId.get().getAccountNum())) + .gas(GAS_LIMIT_FOR_CALL * 4) + .via(INNER_TXN))), + getTxnRecord(INNER_TXN).hasPriority(recordWith().status(SUCCESS)), + getAccountBalance(INTERNAL_CALLER_CONTRACT).hasTinyBars(changeFromSnapshot("initialBalance", -1))); } @HapiTest @@ -1392,24 +1300,20 @@ final Stream internalCallToExistingSystemAccount800ResultsInSuccess AtomicReference targetId = new AtomicReference<>(); targetId.set(AccountID.newBuilder().setAccountNum(800L).build()); - return defaultHapiSpec("internalCallToExistingSystemAccount800ResultsInSuccessNoop") - .given( - uploadInitCode(INTERNAL_CALLER_CONTRACT), - contractCreate(INTERNAL_CALLER_CONTRACT).balance(ONE_HBAR)) - .when( - balanceSnapshot("initialBalance", INTERNAL_CALLER_CONTRACT), - withOpContext((spec, op) -> allRunFor( - spec, - contractCall( - INTERNAL_CALLER_CONTRACT, - CALL_EXTERNAL_FUNCTION, - mirrorAddrWith(targetId.get().getAccountNum())) - .gas(GAS_LIMIT_FOR_CALL * 4) - .via(INNER_TXN)))) - .then( - getTxnRecord(INNER_TXN).hasPriority(recordWith().status(SUCCESS)), - getAccountBalance(INTERNAL_CALLER_CONTRACT) - .hasTinyBars(changeFromSnapshot("initialBalance", 0))); + return hapiTest( + uploadInitCode(INTERNAL_CALLER_CONTRACT), + contractCreate(INTERNAL_CALLER_CONTRACT).balance(ONE_HBAR), + balanceSnapshot("initialBalance", INTERNAL_CALLER_CONTRACT), + withOpContext((spec, op) -> allRunFor( + spec, + contractCall( + INTERNAL_CALLER_CONTRACT, + CALL_EXTERNAL_FUNCTION, + mirrorAddrWith(targetId.get().getAccountNum())) + .gas(GAS_LIMIT_FOR_CALL * 4) + .via(INNER_TXN))), + getTxnRecord(INNER_TXN).hasPriority(recordWith().status(SUCCESS)), + getAccountBalance(INTERNAL_CALLER_CONTRACT).hasTinyBars(changeFromSnapshot("initialBalance", 0))); } @HapiTest @@ -1433,10 +1337,11 @@ contract, BALANCE_OF, mirrorAddrWith(existingSystemAccounts.get(i))) ContractFnResultAsserts.isEqualOrGreaterThan( BigInteger.valueOf(systemAccountBalance)))); } - return defaultHapiSpec("verifiesSystemAccountBalanceOf") - .given(cryptoCreate("testAccount").balance(balance), uploadInitCode(contract), contractCreate(contract)) - .when() - .then(opsArray); + return hapiTest(flattened( + cryptoCreate("testAccount").balance(balance), + uploadInitCode(contract), + contractCreate(contract), + opsArray)); } @HapiTest @@ -1460,29 +1365,29 @@ contract, BALANCE_OF, mirrorAddrWith(nonExistingSystemAccounts.get(i))) ContractFnResultAsserts.isLiteralResult( new Object[] {BigInteger.valueOf(systemAccountBalance)}))); } - return defaultHapiSpec("verifiesSystemAccountBalanceOf") - .given(cryptoCreate("testAccount").balance(balance), uploadInitCode(contract), contractCreate(contract)) - .when() - .then(opsArray); + return hapiTest(flattened( + cryptoCreate("testAccount").balance(balance), + uploadInitCode(contract), + contractCreate(contract), + opsArray)); } @HapiTest final Stream directCallToSystemAccountResultsInSuccessfulNoOp() { - return defaultHapiSpec("directCallToSystemAccountResultsInSuccessfulNoOp") - .given( - cryptoCreate("account").balance(ONE_HUNDRED_HBARS), - withOpContext((spec, opLog) -> spec.registry() - .saveContractId( - "contract", - asContractIdWithEvmAddress(ByteString.copyFrom( - unhex("0000000000000000000000000000000000000275")))))) - .when(withOpContext((spec, ctxLog) -> allRunFor( + return hapiTest( + cryptoCreate("account").balance(ONE_HUNDRED_HBARS), + withOpContext((spec, opLog) -> spec.registry() + .saveContractId( + "contract", + asContractIdWithEvmAddress( + ByteString.copyFrom(unhex("0000000000000000000000000000000000000275"))))), + withOpContext((spec, ctxLog) -> allRunFor( spec, contractCallWithFunctionAbi("contract", getABIFor(FUNCTION, NAME, ERC_721_ABI)) .gas(GAS_LIMIT_FOR_CALL) .via("callToSystemAddress") - .signingWith("account")))) - .then(getTxnRecord("callToSystemAddress") + .signingWith("account"))), + getTxnRecord("callToSystemAddress") .hasPriority(recordWith() .status(SUCCESS) .contractCallResult(resultWith().gasUsed(GAS_LIMIT_FOR_CALL)))); @@ -1493,10 +1398,7 @@ final Stream testCallOperationsForSystemAccounts() { final var contract = "CallOperationsCheckerSuccess"; final var functionName = "call"; final HapiSpecOperation[] opsArray = getCallOperationsOnSystemAccounts(contract, functionName); - return defaultHapiSpec("testCallOperationsForSystemAccounts") - .given(uploadInitCode(contract), contractCreate(contract)) - .when() - .then(opsArray); + return hapiTest(flattened(uploadInitCode(contract), contractCreate(contract), opsArray)); } @HapiTest @@ -1504,10 +1406,7 @@ final Stream testCallCodeOperationsForSystemAccounts() { final var contract = "CallOperationsCheckerSuccess"; final var functionName = "callCode"; final HapiSpecOperation[] opsArray = getCallOperationsOnSystemAccounts(contract, functionName); - return defaultHapiSpec("testCallCodeOperationsForSystemAccounts") - .given(uploadInitCode(contract), contractCreate(contract)) - .when() - .then(opsArray); + return hapiTest(flattened(uploadInitCode(contract), contractCreate(contract), opsArray)); } @HapiTest @@ -1515,10 +1414,7 @@ final Stream testDelegateCallOperationsForSystemAccounts() { final var contract = "CallOperationsCheckerSuccess"; final var functionName = "delegateCall"; final HapiSpecOperation[] opsArray = getCallOperationsOnSystemAccounts(contract, functionName); - return defaultHapiSpec("testDelegateCallOperationsForSystemAccounts") - .given(uploadInitCode(contract), contractCreate(contract)) - .when() - .then(opsArray); + return hapiTest(flattened(uploadInitCode(contract), contractCreate(contract), opsArray)); } @HapiTest @@ -1526,10 +1422,7 @@ final Stream testStaticCallOperationsForSystemAccounts() { final var contract = "CallOperationsCheckerSuccess"; final var functionName = "staticcall"; final HapiSpecOperation[] opsArray = getCallOperationsOnSystemAccounts(contract, functionName); - return defaultHapiSpec("testStaticCallOperationsForSystemAccounts") - .given(uploadInitCode(contract), contractCreate(contract)) - .when() - .then(opsArray); + return hapiTest(flattened(uploadInitCode(contract), contractCreate(contract), opsArray)); } private HapiSpecOperation[] getCallOperationsOnSystemAccounts(final String contract, final String functionName) { diff --git a/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/hapi/ContractCallHapiOnlySuite.java b/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/hapi/ContractCallHapiOnlySuite.java index 8bab36c4e295..165d082fadb4 100644 --- a/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/hapi/ContractCallHapiOnlySuite.java +++ b/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/hapi/ContractCallHapiOnlySuite.java @@ -17,7 +17,7 @@ package com.hedera.services.bdd.suites.contract.hapi; import static com.hedera.services.bdd.junit.TestTags.SMART_CONTRACT; -import static com.hedera.services.bdd.spec.HapiSpec.defaultHapiSpec; +import static com.hedera.services.bdd.spec.HapiSpec.hapiTest; import static com.hedera.services.bdd.spec.assertions.AccountInfoAsserts.changeFromSnapshot; import static com.hedera.services.bdd.spec.keys.KeyFactory.KeyType.THRESHOLD; import static com.hedera.services.bdd.spec.queries.QueryVerbs.getAccountBalance; @@ -53,15 +53,14 @@ public class ContractCallHapiOnlySuite { @HapiTest final Stream callFailsWhenAmountIsNegativeButStillChargedFee() { final var payer = "payer"; - return defaultHapiSpec("callFailsWhenAmountIsNegativeButStillChargedFee") - .given( - uploadInitCode(PAY_RECEIVABLE_CONTRACT), - contractCreate(PAY_RECEIVABLE_CONTRACT) - .adminKey(THRESHOLD) - .gas(1_000_000) - .refusingEthConversion(), - cryptoCreate(payer).balance(ONE_MILLION_HBARS).payingWith(GENESIS)) - .when(withOpContext((spec, ignore) -> { + return hapiTest( + uploadInitCode(PAY_RECEIVABLE_CONTRACT), + contractCreate(PAY_RECEIVABLE_CONTRACT) + .adminKey(THRESHOLD) + .gas(1_000_000) + .refusingEthConversion(), + cryptoCreate(payer).balance(ONE_MILLION_HBARS).payingWith(GENESIS), + withOpContext((spec, ignore) -> { final var subop1 = balanceSnapshot("balanceBefore0", payer); final var subop2 = contractCall(PAY_RECEIVABLE_CONTRACT) .via(PAY_TXN) @@ -78,7 +77,6 @@ final Stream callFailsWhenAmountIsNegativeButStillChargedFee() { final var subop4 = getAccountBalance(payer).hasTinyBars(changeFromSnapshot("balanceBefore0", -delta)); allRunFor(spec, subop4); - })) - .then(); + })); } } diff --git a/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/hapi/ContractCallLocalSuite.java b/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/hapi/ContractCallLocalSuite.java index 605b5b7d571e..d31eb9eb7ff7 100644 --- a/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/hapi/ContractCallLocalSuite.java +++ b/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/hapi/ContractCallLocalSuite.java @@ -19,7 +19,6 @@ import static com.hedera.node.app.hapi.utils.EthSigsUtils.recoverAddressFromPubKey; import static com.hedera.services.bdd.junit.TestTags.SMART_CONTRACT; import static com.hedera.services.bdd.spec.HapiPropertySource.asSolidityAddress; -import static com.hedera.services.bdd.spec.HapiSpec.defaultHapiSpec; import static com.hedera.services.bdd.spec.HapiSpec.hapiTest; import static com.hedera.services.bdd.spec.assertions.ContractFnResultAsserts.isLiteralResult; import static com.hedera.services.bdd.spec.assertions.ContractFnResultAsserts.resultWith; @@ -162,10 +161,11 @@ final Stream htsOwnershipCheckWorksWithAliasAddress() { @HapiTest final Stream idVariantsTreatedAsExpected() { - return defaultHapiSpec("idVariantsTreatedAsExpected") - .given(uploadInitCode(CONTRACT), contractCreate(CONTRACT).adminKey(THRESHOLD)) - .when(contractCall(CONTRACT, "create").gas(785_000)) - .then(sendModified(withSuccessivelyVariedQueryIds(), () -> contractCallLocal(CONTRACT, "getIndirect"))); + return hapiTest( + uploadInitCode(CONTRACT), + contractCreate(CONTRACT).adminKey(THRESHOLD), + contractCall(CONTRACT, "create").gas(785_000), + sendModified(withSuccessivelyVariedQueryIds(), () -> contractCallLocal(CONTRACT, "getIndirect"))); } @HapiTest diff --git a/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/hapi/ContractCallSuite.java b/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/hapi/ContractCallSuite.java index c51435c473d9..208543af157b 100644 --- a/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/hapi/ContractCallSuite.java +++ b/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/hapi/ContractCallSuite.java @@ -24,7 +24,6 @@ import static com.hedera.services.bdd.spec.HapiPropertySource.asHexedSolidityAddress; import static com.hedera.services.bdd.spec.HapiPropertySource.contractIdFromHexedMirrorAddress; import static com.hedera.services.bdd.spec.HapiPropertySource.idAsHeadlongAddress; -import static com.hedera.services.bdd.spec.HapiSpec.defaultHapiSpec; import static com.hedera.services.bdd.spec.HapiSpec.hapiTest; import static com.hedera.services.bdd.spec.assertions.AccountInfoAsserts.changeFromSnapshot; import static com.hedera.services.bdd.spec.assertions.AssertUtils.inOrder; @@ -224,10 +223,7 @@ public class ContractCallSuite { @HapiTest final Stream canHandleInvalidContractCallTransactions() { - return defaultHapiSpec("canHandleInvalidContractCallTransactions") - .given() - .when() - .then(contractCall(null).hasPrecheck(INVALID_CONTRACT_ID)); + return hapiTest(contractCall(null).hasPrecheck(INVALID_CONTRACT_ID)); } @HapiTest @@ -263,33 +259,26 @@ final Stream insufficientGasToPrecompileFailsWithInterpretableActio final var altbn128PairingAddress = asHeadlongAddress("0x08"); final var htsSystemContractAddress = asHeadlongAddress("0x0167"); final var tokenInfoFn = new Function("getTokenInfo(address)"); - return defaultHapiSpec("insufficientGasToPrecompileFailsWithInterpretableActionSidecars") - .given( - recordStreamMustIncludeNoFailuresFrom(sidecarIdValidator()), - uploadInitCode(contract), - contractCreate(contract)) - .when(tokenCreate("someToken").exposingAddressTo(someTokenAddress::set)) - .then( - // Generates CONTRACT_ACTION sidecars for a call to an EVM precompile - // with insufficient gas - contractCall( - contract, - "callRequested", - altbn128PairingAddress, - payload, - BigInteger.valueOf(11_256)) - .hasKnownStatus(CONTRACT_REVERT_EXECUTED), - // Generates CONTRACT_ACTION sidecars for a call to an HTS - // system contract with insufficient gas - sourcing(() -> contractCall( - contract, - "callRequested", - htsSystemContractAddress, - tokenInfoFn - .encodeCallWithArgs(someTokenAddress.get()) - .array(), - BigInteger.valueOf(1)) - .hasKnownStatus(CONTRACT_REVERT_EXECUTED))); + return hapiTest( + recordStreamMustIncludeNoFailuresFrom(sidecarIdValidator()), + uploadInitCode(contract), + contractCreate(contract), + tokenCreate("someToken").exposingAddressTo(someTokenAddress::set), + // Generates CONTRACT_ACTION sidecars for a call to an EVM precompile + // with insufficient gas + contractCall(contract, "callRequested", altbn128PairingAddress, payload, BigInteger.valueOf(11_256)) + .hasKnownStatus(CONTRACT_REVERT_EXECUTED), + // Generates CONTRACT_ACTION sidecars for a call to an HTS + // system contract with insufficient gas + sourcing(() -> contractCall( + contract, + "callRequested", + htsSystemContractAddress, + tokenInfoFn + .encodeCallWithArgs(someTokenAddress.get()) + .array(), + BigInteger.valueOf(1)) + .hasKnownStatus(CONTRACT_REVERT_EXECUTED))); } @HapiTest @@ -1455,14 +1444,13 @@ final Stream payableSuccess() { @HapiTest final Stream idVariantsTreatedAsExpected() { - return defaultHapiSpec("idVariantsTreatedAsExpected") - .given(uploadInitCode(PAY_RECEIVABLE_CONTRACT), contractCreate(PAY_RECEIVABLE_CONTRACT)) - .when() - .then( - submitModified(withSuccessivelyVariedBodyIds(), () -> contractCall(PAY_RECEIVABLE_CONTRACT)), - // It's also ok to use a default PBJ ContractID (i.e. an id with - // UNSET contract oneof) to make a no-op call to address 0x00...00 - contractCall(DEFAULT_ID_SENTINEL)); + return hapiTest( + uploadInitCode(PAY_RECEIVABLE_CONTRACT), + contractCreate(PAY_RECEIVABLE_CONTRACT), + submitModified(withSuccessivelyVariedBodyIds(), () -> contractCall(PAY_RECEIVABLE_CONTRACT)), + // It's also ok to use a default PBJ ContractID (i.e. an id with + // UNSET contract oneof) to make a no-op call to address 0x00...00 + contractCall(DEFAULT_ID_SENTINEL)); } @HapiTest @@ -2309,12 +2297,12 @@ final Stream consTimeManagementWorksWithRevertedInternalCreations() final Stream callStaticCallToLargeAddress() { final var txn = "txn"; final var contract = "CallInConstructor"; - return defaultHapiSpec("callStaticAddress") - .given( - uploadInitCode(contract), - contractCreate(contract).via(txn).hasKnownStatus(SUCCESS)) - .when(contractCall(contract, "callSomebody").via(txn)) - .then(getTxnRecord(txn).logged(), withOpContext((spec, opLog) -> { + return hapiTest( + uploadInitCode(contract), + contractCreate(contract).via(txn).hasKnownStatus(SUCCESS), + contractCall(contract, "callSomebody").via(txn), + getTxnRecord(txn).logged(), + withOpContext((spec, opLog) -> { final var op = getTxnRecord(txn); allRunFor(spec, op); final var record = op.getResponseRecord(); @@ -2335,55 +2323,48 @@ final Stream htsCallWithInsufficientGasHasNoStateChanges() { final AtomicReference
receiverAddress = new AtomicReference<>(); final AtomicReference
tokenAddress = new AtomicReference<>(); final var initialSupply = 100L; - return defaultHapiSpec("htsCallWithInsufficientGasHasNoStateChanges") - .given( - cryptoCreate(TOKEN_TREASURY).exposingEvmAddressTo(treasuryAddress::set), - cryptoCreate(CIVILIAN_PAYER) - .exposingEvmAddressTo(receiverAddress::set) - .maxAutomaticTokenAssociations(1), - tokenCreate(TOKEN) - .treasury(TOKEN_TREASURY) - .initialSupply(initialSupply) - .exposingAddressTo(tokenAddress::set), - uploadInitCode(contract), - contractCreate(contract), - cryptoApproveAllowance() - .addTokenAllowance(TOKEN_TREASURY, TOKEN, contract, 100) - .signedBy(DEFAULT_PAYER, TOKEN_TREASURY)) - .when() - .then( - // Call transferToken() with insufficent gas - sourcing(() -> contractCall( - contract, - "callRequestedAndIgnoreFailure", - htsSystemContractAddress, - transferToken - .encodeCallWithArgs( - tokenAddress.get(), - treasuryAddress.get(), - receiverAddress.get(), - 13L) - .array(), - BigInteger.valueOf(13_000L)) - .via("callTxn")), - childRecordsCheck("callTxn", SUCCESS, recordWith().status(INSUFFICIENT_GAS)), - // Verify no token balances changed - getAccountDetails(TOKEN_TREASURY) - .hasToken(relationshipWith(TOKEN).balance(initialSupply)), - getAccountDetails(CIVILIAN_PAYER).hasNoTokenRelationship(TOKEN)); + return hapiTest( + cryptoCreate(TOKEN_TREASURY).exposingEvmAddressTo(treasuryAddress::set), + cryptoCreate(CIVILIAN_PAYER) + .exposingEvmAddressTo(receiverAddress::set) + .maxAutomaticTokenAssociations(1), + tokenCreate(TOKEN) + .treasury(TOKEN_TREASURY) + .initialSupply(initialSupply) + .exposingAddressTo(tokenAddress::set), + uploadInitCode(contract), + contractCreate(contract), + cryptoApproveAllowance() + .addTokenAllowance(TOKEN_TREASURY, TOKEN, contract, 100) + .signedBy(DEFAULT_PAYER, TOKEN_TREASURY), + + // Call transferToken() with insufficent gas + sourcing(() -> contractCall( + contract, + "callRequestedAndIgnoreFailure", + htsSystemContractAddress, + transferToken + .encodeCallWithArgs( + tokenAddress.get(), treasuryAddress.get(), receiverAddress.get(), 13L) + .array(), + BigInteger.valueOf(13_000L)) + .via("callTxn")), + childRecordsCheck("callTxn", SUCCESS, recordWith().status(INSUFFICIENT_GAS)), + // Verify no token balances changed + getAccountDetails(TOKEN_TREASURY) + .hasToken(relationshipWith(TOKEN).balance(initialSupply)), + getAccountDetails(CIVILIAN_PAYER).hasNoTokenRelationship(TOKEN)); } @HapiTest final Stream callToNonExtantLongZeroAddressUsesTargetedAddress() { final var contract = "LowLevelCall"; final var nonExtantMirrorAddress = asHeadlongAddress("0xE8D4A50FFF"); - return defaultHapiSpec("callToNonExtantLongZeroAddressUsesTargetedAddress") - .given( - recordStreamMustIncludeNoFailuresFrom(sidecarIdValidator()), - uploadInitCode(contract), - contractCreate(contract)) - .when() - .then(contractCall( + return hapiTest( + recordStreamMustIncludeNoFailuresFrom(sidecarIdValidator()), + uploadInitCode(contract), + contractCreate(contract), + contractCall( contract, "callRequested", nonExtantMirrorAddress, new byte[0], BigInteger.valueOf(88_888L))); } @@ -2391,14 +2372,11 @@ final Stream callToNonExtantLongZeroAddressUsesTargetedAddress() { final Stream callToNonExtantEvmAddressUsesTargetedAddress() { final var contract = "LowLevelCall"; final var nonExtantEvmAddress = asHeadlongAddress(TxnUtils.randomUtf8Bytes(20)); - return defaultHapiSpec("callToNonExtantEvmAddressUsesTargetedAddress") - .given( - recordStreamMustIncludeNoFailuresFrom(sidecarIdValidator()), - uploadInitCode(contract), - contractCreate(contract)) - .when() - .then(contractCall( - contract, "callRequested", nonExtantEvmAddress, new byte[0], BigInteger.valueOf(88_888L))); + return hapiTest( + recordStreamMustIncludeNoFailuresFrom(sidecarIdValidator()), + uploadInitCode(contract), + contractCreate(contract), + contractCall(contract, "callRequested", nonExtantEvmAddress, new byte[0], BigInteger.valueOf(88_888L))); } @HapiTest @@ -2406,16 +2384,15 @@ final Stream failsWithLessThanIntrinsicGas() { final String randomContract = "0.0.1051"; final String functionName = "name"; final String contractName = "ERC721ABI"; - return defaultHapiSpec("failsWithLessThanIntrinsicGas") - .given(cryptoCreate(ACCOUNT).balance(ONE_HUNDRED_HBARS), withOpContext((spec, opLog) -> spec.registry() - .saveContractId(CONTRACT, asContract(randomContract)))) - .when(withOpContext((spec, ctxLog) -> allRunFor( + return hapiTest( + cryptoCreate(ACCOUNT).balance(ONE_HUNDRED_HBARS), + withOpContext((spec, opLog) -> spec.registry().saveContractId(CONTRACT, asContract(randomContract))), + withOpContext((spec, ctxLog) -> allRunFor( spec, contractCallWithFunctionAbi(CONTRACT, getABIFor(FUNCTION, functionName, contractName)) .gas(INTRINSIC_GAS_FOR_0_ARG_METHOD - 1) .signingWith(ACCOUNT) - .hasPrecheck(INSUFFICIENT_GAS)))) - .then(); + .hasPrecheck(INSUFFICIENT_GAS)))); } @HapiTest diff --git a/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/hapi/ContractCreateSuite.java b/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/hapi/ContractCreateSuite.java index d7940ea647a6..4002c6eca302 100644 --- a/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/hapi/ContractCreateSuite.java +++ b/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/hapi/ContractCreateSuite.java @@ -17,7 +17,6 @@ package com.hedera.services.bdd.suites.contract.hapi; import static com.hedera.services.bdd.junit.TestTags.SMART_CONTRACT; -import static com.hedera.services.bdd.spec.HapiSpec.defaultHapiSpec; import static com.hedera.services.bdd.spec.HapiSpec.hapiTest; import static com.hedera.services.bdd.spec.assertions.AccountInfoAsserts.accountWith; import static com.hedera.services.bdd.spec.assertions.AssertUtils.inOrder; @@ -164,16 +163,15 @@ final Stream createDeterministicDeployer() { final var transaction = ByteString.copyFrom(CommonUtils.unhex(DEPLOYMENT_TRANSACTION)); final var systemFileId = FileID.newBuilder().setFileNum(159).build(); - return defaultHapiSpec("createDeterministicDeployer") - .given( - newKeyNamed(SECP_256K1_SOURCE_KEY).shape(SECP_256K1_SHAPE), - cryptoCreate(PAYER).balance(6 * ONE_MILLION_HBARS), - cryptoCreate(RELAYER).balance(6 * ONE_MILLION_HBARS), - cryptoTransfer(tinyBarsFromTo(PAYER, creatorAddress, ONE_HUNDRED_HBARS))) - .when(explicitEthereumTransaction(DEPLOYER, (spec, b) -> b.setCallData(systemFileId) + return hapiTest( + newKeyNamed(SECP_256K1_SOURCE_KEY).shape(SECP_256K1_SHAPE), + cryptoCreate(PAYER).balance(6 * ONE_MILLION_HBARS), + cryptoCreate(RELAYER).balance(6 * ONE_MILLION_HBARS), + cryptoTransfer(tinyBarsFromTo(PAYER, creatorAddress, ONE_HUNDRED_HBARS)), + explicitEthereumTransaction(DEPLOYER, (spec, b) -> b.setCallData(systemFileId) .setEthereumData(transaction)) - .payingWith(PAYER)) - .then(getContractInfo(DEPLOYER) + .payingWith(PAYER), + getContractInfo(DEPLOYER) .has(contractWith().addressOrAlias(EXPECTED_DEPLOYER_ADDRESS)) .logged()); } @@ -254,19 +252,16 @@ final Stream insufficientPayerBalanceUponCreation() { @HapiTest final Stream disallowCreationsOfEmptyInitCode() { final var contract = "EmptyContract"; - return defaultHapiSpec("allowCreationsOfEmptyContract") - .given( - newKeyNamed(ADMIN_KEY), - // refuse eth conversion because we can't set invalid bytecode to callData in ethereum - // transaction - contractCreate(contract) - .adminKey(ADMIN_KEY) - .entityMemo("Empty Contract") - .inlineInitCode(ByteString.EMPTY) - .hasKnownStatus(CONTRACT_BYTECODE_EMPTY) - .refusingEthConversion()) - .when() - .then(); + return hapiTest( + newKeyNamed(ADMIN_KEY), + // refuse eth conversion because we can't set invalid bytecode to callData in ethereum + // transaction + contractCreate(contract) + .adminKey(ADMIN_KEY) + .entityMemo("Empty Contract") + .inlineInitCode(ByteString.EMPTY) + .hasKnownStatus(CONTRACT_BYTECODE_EMPTY) + .refusingEthConversion()); } @HapiTest @@ -284,37 +279,30 @@ final Stream cannotSendToNonExistentAccount() { final Stream invalidSystemInitcodeFileFailsWithInvalidFileId() { final var neverToBe = "NeverToBe"; final var systemFileId = FileID.newBuilder().setFileNum(159).build(); - return defaultHapiSpec("InvalidSystemInitcodeFileFailsWithInvalidFileId") - .given( - newKeyNamed(SECP_256K1_SOURCE_KEY).shape(SECP_256K1_SHAPE), - cryptoCreate(RELAYER).balance(ONE_HUNDRED_HBARS)) - .when() - .then( - explicitContractCreate(neverToBe, (spec, b) -> b.setFileID(systemFileId)) - // refuse eth conversion because we can't set invalid bytecode to callData in ethereum - // transaction - .hasKnownStatus(INVALID_FILE_ID) - .refusingEthConversion(), - explicitEthereumTransaction(neverToBe, (spec, b) -> { - final var signedEthTx = Signing.signMessage( - placeholderEthTx(), - getEcdsaPrivateKeyFromSpec(spec, SECP_256K1_SOURCE_KEY)); - b.setCallData(systemFileId) - .setEthereumData(ByteString.copyFrom(signedEthTx.encodeTx())); - }) - .hasPrecheck(INVALID_FILE_ID)); + return hapiTest( + newKeyNamed(SECP_256K1_SOURCE_KEY).shape(SECP_256K1_SHAPE), + cryptoCreate(RELAYER).balance(ONE_HUNDRED_HBARS), + explicitContractCreate(neverToBe, (spec, b) -> b.setFileID(systemFileId)) + // refuse eth conversion because we can't set invalid bytecode to callData in ethereum + // transaction + .hasKnownStatus(INVALID_FILE_ID) + .refusingEthConversion(), + explicitEthereumTransaction(neverToBe, (spec, b) -> { + final var signedEthTx = Signing.signMessage( + placeholderEthTx(), getEcdsaPrivateKeyFromSpec(spec, SECP_256K1_SOURCE_KEY)); + b.setCallData(systemFileId).setEthereumData(ByteString.copyFrom(signedEthTx.encodeTx())); + }) + .hasPrecheck(INVALID_FILE_ID)); } @HapiTest final Stream createsVanillaContractAsExpectedWithOmittedAdminKey() { - return defaultHapiSpec("createsVanillaContractAsExpectedWithOmittedAdminKey") - .given(uploadInitCode(EMPTY_CONSTRUCTOR_CONTRACT)) - .when() - .then( - contractCreate(EMPTY_CONSTRUCTOR_CONTRACT).omitAdminKey(), - getContractInfo(EMPTY_CONSTRUCTOR_CONTRACT) - .has(contractWith().immutableContractKey(EMPTY_CONSTRUCTOR_CONTRACT)) - .logged()); + return hapiTest( + uploadInitCode(EMPTY_CONSTRUCTOR_CONTRACT), + contractCreate(EMPTY_CONSTRUCTOR_CONTRACT).omitAdminKey(), + getContractInfo(EMPTY_CONSTRUCTOR_CONTRACT) + .has(contractWith().immutableContractKey(EMPTY_CONSTRUCTOR_CONTRACT)) + .logged()); } @LeakyHapiTest(overrides = {"ledger.maxAutoAssociations"}) @@ -428,23 +416,21 @@ final Stream createEmptyConstructor() { @HapiTest final Stream createCallInConstructor() { final var txn = "txn"; - return defaultHapiSpec("callInConstructor") - .given(uploadInitCode("CallInConstructor")) - .when() - .then( - contractCreate("CallInConstructor").via(txn).hasKnownStatus(SUCCESS), - getTxnRecord(txn).logged(), - withOpContext((spec, opLog) -> { - final var op = getTxnRecord(txn); - allRunFor(spec, op); - final var record = op.getResponseRecord(); - final var creationResult = record.getContractCreateResult(); - final var createdIds = creationResult.getCreatedContractIDsList(); - assertEquals(1, createdIds.size(), "Expected one creations but got " + createdIds); - assertTrue( - createdIds.get(0).getContractNum() < 10000, - "Expected contract num < 10000 but got " + createdIds); - })); + return hapiTest( + uploadInitCode("CallInConstructor"), + contractCreate("CallInConstructor").via(txn).hasKnownStatus(SUCCESS), + getTxnRecord(txn).logged(), + withOpContext((spec, opLog) -> { + final var op = getTxnRecord(txn); + allRunFor(spec, op); + final var record = op.getResponseRecord(); + final var creationResult = record.getContractCreateResult(); + final var createdIds = creationResult.getCreatedContractIDsList(); + assertEquals(1, createdIds.size(), "Expected one creations but got " + createdIds); + assertTrue( + createdIds.get(0).getContractNum() < 10000, + "Expected contract num < 10000 but got " + createdIds); + })); } @HapiTest @@ -506,12 +492,11 @@ final Stream createFailsIfMissingSigs() { @HapiTest final Stream rejectsInsufficientGas() { - return defaultHapiSpec("RejectsInsufficientGas") - .given(uploadInitCode(EMPTY_CONSTRUCTOR_CONTRACT)) - .when() + return hapiTest( + uploadInitCode(EMPTY_CONSTRUCTOR_CONTRACT), // refuse eth conversion because ethereum transaction fails in IngestChecker with precheck status // INSUFFICIENT_GAS - .then(contractCreate(EMPTY_CONSTRUCTOR_CONTRACT) + contractCreate(EMPTY_CONSTRUCTOR_CONTRACT) .gas(0L) .hasPrecheck(INSUFFICIENT_GAS) .refusingEthConversion()); @@ -519,17 +504,14 @@ final Stream rejectsInsufficientGas() { @HapiTest final Stream rejectsInvalidMemo() { - return defaultHapiSpec("RejectsInvalidMemo") - .given() - .when() - .then( - uploadInitCode(EMPTY_CONSTRUCTOR_CONTRACT), - contractCreate(EMPTY_CONSTRUCTOR_CONTRACT) - .entityMemo(TxnUtils.nAscii(101)) - .hasPrecheck(MEMO_TOO_LONG), - contractCreate(EMPTY_CONSTRUCTOR_CONTRACT) - .entityMemo(ZERO_BYTE_MEMO) - .hasPrecheck(INVALID_ZERO_BYTE_IN_STRING)); + return hapiTest( + uploadInitCode(EMPTY_CONSTRUCTOR_CONTRACT), + contractCreate(EMPTY_CONSTRUCTOR_CONTRACT) + .entityMemo(TxnUtils.nAscii(101)) + .hasPrecheck(MEMO_TOO_LONG), + contractCreate(EMPTY_CONSTRUCTOR_CONTRACT) + .entityMemo(ZERO_BYTE_MEMO) + .hasPrecheck(INVALID_ZERO_BYTE_IN_STRING)); } @HapiTest @@ -546,11 +528,10 @@ final Stream rejectsInsufficientFee() { @HapiTest final Stream rejectsInvalidBytecode() { final var contract = "InvalidBytecode"; - return defaultHapiSpec("RejectsInvalidBytecode") - .given(uploadInitCode(contract)) - .when() + return hapiTest( + uploadInitCode(contract), // refuse eth conversion because we can't set invalid bytecode to callData in ethereum transaction - .then(contractCreate(contract) + contractCreate(contract) .hasKnownStatus(ERROR_DECODING_BYTESTRING) .refusingEthConversion()); } @@ -728,14 +709,14 @@ final Stream tryContractCreateWithMaxAutoAssoc() { @HapiTest final Stream tryContractCreateWithZeroAutoAssoc() { final var contract = "CreateTrivial"; - return defaultHapiSpec("tryContractCreateWithZeroMaxAutoAssoc") - .given(uploadInitCode(contract)) - .when(contractCreate(contract) + return hapiTest( + uploadInitCode(contract), + contractCreate(contract) .adminKey(THRESHOLD) .refusingEthConversion() .maxAutomaticTokenAssociations(0) - .hasKnownStatus(SUCCESS)) - .then(getContractInfo(contract) + .hasKnownStatus(SUCCESS), + getContractInfo(contract) .has(contractWith().maxAutoAssociations(0)) .logged()); } @@ -743,14 +724,14 @@ final Stream tryContractCreateWithZeroAutoAssoc() { @HapiTest final Stream tryContractCreateWithBalance() { final var contract = "Donor"; - return defaultHapiSpec("tryContractCreateWithBalance") - .given(uploadInitCode(contract)) - .when(contractCreate(contract) + return hapiTest( + uploadInitCode(contract), + contractCreate(contract) .adminKey(THRESHOLD) .refusingEthConversion() .balance(ONE_HUNDRED_HBARS) - .hasKnownStatus(SUCCESS)) - .then(getContractInfo(contract) + .hasKnownStatus(SUCCESS), + getContractInfo(contract) .has(contractWith().maxAutoAssociations(0).balance(ONE_HUNDRED_HBARS)) .logged()); } @@ -759,30 +740,29 @@ final Stream contractCreateShouldChargeTheSame() { final var createFeeWithMaxAutoAssoc = 10L; final var contract1 = "EmptyOne"; final var contract2 = "EmptyTwo"; - return defaultHapiSpec("contractCreateShouldChargeTheSame") - .given(uploadInitCode(contract1), uploadInitCode(contract2)) - .when( - contractCreate(contract1) - .via(contract1) - .adminKey(THRESHOLD) - .refusingEthConversion() - .maxAutomaticTokenAssociations(1) - .hasKnownStatus(SUCCESS), - contractCreate(contract2) - .via(contract2) - .adminKey(THRESHOLD) - .refusingEthConversion() - .maxAutomaticTokenAssociations(1000) - .hasKnownStatus(SUCCESS)) - .then( - getContractInfo(contract1) - .has(contractWith().maxAutoAssociations(1)) - .logged(), - getTxnRecord(contract1).fee(createFeeWithMaxAutoAssoc).logged(), - getContractInfo(contract2) - .has(contractWith().maxAutoAssociations(1000)) - .logged(), - getTxnRecord(contract2).fee(createFeeWithMaxAutoAssoc).logged()); + return hapiTest( + uploadInitCode(contract1), + uploadInitCode(contract2), + contractCreate(contract1) + .via(contract1) + .adminKey(THRESHOLD) + .refusingEthConversion() + .maxAutomaticTokenAssociations(1) + .hasKnownStatus(SUCCESS), + contractCreate(contract2) + .via(contract2) + .adminKey(THRESHOLD) + .refusingEthConversion() + .maxAutomaticTokenAssociations(1000) + .hasKnownStatus(SUCCESS), + getContractInfo(contract1) + .has(contractWith().maxAutoAssociations(1)) + .logged(), + getTxnRecord(contract1).fee(createFeeWithMaxAutoAssoc).logged(), + getContractInfo(contract2) + .has(contractWith().maxAutoAssociations(1000)) + .logged(), + getTxnRecord(contract2).fee(createFeeWithMaxAutoAssoc).logged()); } @HapiTest @@ -841,10 +821,10 @@ final Stream idVariantsTreatedAsExpected() { final var autoRenewAccount = "autoRenewAccount"; final var creationNumber = new AtomicLong(); final var contract = "CreateTrivial"; - return defaultHapiSpec("idVariantsTreatedAsExpected") - .given(uploadInitCode(contract), cryptoCreate(autoRenewAccount).balance(ONE_HUNDRED_HBARS)) - .when() - .then(submitModified(withSuccessivelyVariedBodyIds(), () -> contractCreate( + return hapiTest( + uploadInitCode(contract), + cryptoCreate(autoRenewAccount).balance(ONE_HUNDRED_HBARS), + submitModified(withSuccessivelyVariedBodyIds(), () -> contractCreate( "contract" + creationNumber.getAndIncrement()) .bytecode(contract) .autoRenewAccountId(autoRenewAccount))); diff --git a/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/hapi/ContractDeleteSuite.java b/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/hapi/ContractDeleteSuite.java index 27fc721d351a..fddcd133ab68 100644 --- a/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/hapi/ContractDeleteSuite.java +++ b/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/hapi/ContractDeleteSuite.java @@ -18,7 +18,6 @@ import static com.hedera.services.bdd.junit.TestTags.SMART_CONTRACT; import static com.hedera.services.bdd.spec.HapiPropertySource.asHexedSolidityAddress; -import static com.hedera.services.bdd.spec.HapiSpec.defaultHapiSpec; import static com.hedera.services.bdd.spec.HapiSpec.hapiTest; import static com.hedera.services.bdd.spec.assertions.ContractFnResultAsserts.resultWith; import static com.hedera.services.bdd.spec.assertions.ContractInfoAsserts.contractWith; @@ -98,20 +97,17 @@ public class ContractDeleteSuite { @HapiTest final Stream idVariantsTreatedAsExpected() { - return defaultHapiSpec("idVariantsTreatedAsExpected") - .given( - newKeyNamed("adminKey"), - uploadInitCode(CONTRACT), - contractCreate(CONTRACT), - cryptoCreate("transferAccount")) - .when( - contractCreate("a").bytecode(CONTRACT).adminKey("adminKey"), - contractCreate("b").bytecode(CONTRACT).adminKey("adminKey")) - .then( - submitModified(withSuccessivelyVariedBodyIds(), () -> contractDelete("a") - .transferAccount("transferAccount")), - submitModified(withSuccessivelyVariedBodyIds(), () -> contractDelete("b") - .transferContract(CONTRACT))); + return hapiTest( + newKeyNamed("adminKey"), + uploadInitCode(CONTRACT), + contractCreate(CONTRACT), + cryptoCreate("transferAccount"), + contractCreate("a").bytecode(CONTRACT).adminKey("adminKey"), + contractCreate("b").bytecode(CONTRACT).adminKey("adminKey"), + submitModified(withSuccessivelyVariedBodyIds(), () -> contractDelete("a") + .transferAccount("transferAccount")), + submitModified(withSuccessivelyVariedBodyIds(), () -> contractDelete("b") + .transferContract(CONTRACT))); } @HapiTest @@ -205,40 +201,38 @@ final Stream cannotDeleteOrSelfDestructTokenTreasury() { final var multiKey = "multi"; final var escapeRoute = "civilian"; final var beneficiary = "beneficiary"; - return defaultHapiSpec("CannotDeleteOrSelfDestructTokenTreasury") - .given( - cryptoCreate(beneficiary).balance(ONE_HUNDRED_HBARS), - newKeyNamed(multiKey), - cryptoCreate(escapeRoute), - uploadInitCode(selfDestructCallable), - contractCustomCreate(selfDestructCallable, "1") - .adminKey(multiKey) - .balance(123) - // Refusing ethereum create conversion, because we get INVALID_SIGNATURE upon - // tokenAssociate, - // since we have CONTRACT_ID key - .refusingEthConversion(), - contractCustomCreate(selfDestructCallable, "2") - .adminKey(multiKey) - .balance(321) - // Refusing ethereum create conversion, because we get INVALID_SIGNATURE upon - // tokenAssociate, - // since we have CONTRACT_ID key - .refusingEthConversion(), - tokenCreate(someToken).adminKey(multiKey).treasury(selfDestructCallable + "1")) - .when( - contractDelete(selfDestructCallable + "1").hasKnownStatus(ACCOUNT_IS_TREASURY), - tokenAssociate(selfDestructCallable + "2", someToken), - tokenUpdate(someToken) - .treasury(selfDestructCallable + "2") - .signedByPayerAnd(multiKey, selfDestructCallable + "2"), - contractDelete(selfDestructCallable + "1"), - contractCall(selfDestructCallable + "2", CONTRACT_DESTROY) - .hasKnownStatus(CONTRACT_EXECUTION_EXCEPTION) - .payingWith(beneficiary), - tokenAssociate(escapeRoute, someToken), - tokenUpdate(someToken).treasury(escapeRoute).signedByPayerAnd(multiKey, escapeRoute)) - .then(contractCall(selfDestructCallable + "2", CONTRACT_DESTROY).payingWith(beneficiary)); + return hapiTest( + cryptoCreate(beneficiary).balance(ONE_HUNDRED_HBARS), + newKeyNamed(multiKey), + cryptoCreate(escapeRoute), + uploadInitCode(selfDestructCallable), + contractCustomCreate(selfDestructCallable, "1") + .adminKey(multiKey) + .balance(123) + // Refusing ethereum create conversion, because we get INVALID_SIGNATURE upon + // tokenAssociate, + // since we have CONTRACT_ID key + .refusingEthConversion(), + contractCustomCreate(selfDestructCallable, "2") + .adminKey(multiKey) + .balance(321) + // Refusing ethereum create conversion, because we get INVALID_SIGNATURE upon + // tokenAssociate, + // since we have CONTRACT_ID key + .refusingEthConversion(), + tokenCreate(someToken).adminKey(multiKey).treasury(selfDestructCallable + "1"), + contractDelete(selfDestructCallable + "1").hasKnownStatus(ACCOUNT_IS_TREASURY), + tokenAssociate(selfDestructCallable + "2", someToken), + tokenUpdate(someToken) + .treasury(selfDestructCallable + "2") + .signedByPayerAnd(multiKey, selfDestructCallable + "2"), + contractDelete(selfDestructCallable + "1"), + contractCall(selfDestructCallable + "2", CONTRACT_DESTROY) + .hasKnownStatus(CONTRACT_EXECUTION_EXCEPTION) + .payingWith(beneficiary), + tokenAssociate(escapeRoute, someToken), + tokenUpdate(someToken).treasury(escapeRoute).signedByPayerAnd(multiKey, escapeRoute), + contractCall(selfDestructCallable + "2", CONTRACT_DESTROY).payingWith(beneficiary)); } @HapiTest @@ -283,107 +277,99 @@ final Stream cannotDeleteOrSelfDestructContractWithNonZeroBalance() @HapiTest final Stream rejectsWithoutProperSig() { - return defaultHapiSpec("rejectsWithoutProperSig") + return hapiTest( // Refusing ethereum create conversion, because we get INVALID_SIGNATURE upon tokenAssociate, // since we have CONTRACT_ID key - .given(uploadInitCode(CONTRACT), contractCreate(CONTRACT).refusingEthConversion()) - .when() - .then(contractDelete(CONTRACT).signedBy(GENESIS).hasKnownStatus(INVALID_SIGNATURE)); + uploadInitCode(CONTRACT), + contractCreate(CONTRACT).refusingEthConversion(), + contractDelete(CONTRACT).signedBy(GENESIS).hasKnownStatus(INVALID_SIGNATURE)); } @HapiTest final Stream systemCannotDeleteOrUndeleteContracts() { - return defaultHapiSpec("SystemCannotDeleteOrUndeleteContracts") - .given(uploadInitCode(CONTRACT), contractCreate(CONTRACT)) - .when() - .then( - systemContractDelete(CONTRACT) - .payingWith(SYSTEM_DELETE_ADMIN) - .hasPrecheck(NOT_SUPPORTED), - systemContractUndelete(CONTRACT) - .payingWith(SYSTEM_UNDELETE_ADMIN) - .hasPrecheck(NOT_SUPPORTED), - getContractInfo(CONTRACT).hasAnswerOnlyPrecheck(OK)); + return hapiTest( + uploadInitCode(CONTRACT), + contractCreate(CONTRACT), + systemContractDelete(CONTRACT).payingWith(SYSTEM_DELETE_ADMIN).hasPrecheck(NOT_SUPPORTED), + systemContractUndelete(CONTRACT) + .payingWith(SYSTEM_UNDELETE_ADMIN) + .hasPrecheck(NOT_SUPPORTED), + getContractInfo(CONTRACT).hasAnswerOnlyPrecheck(OK)); } @HapiTest final Stream deleteWorksWithMutableContract() { final var tbdFile = "FTBD"; final var tbdContract = "CTBD"; - return defaultHapiSpec("DeleteWorksWithMutableContract") - .given( - fileCreate(tbdFile), - fileDelete(tbdFile), - // refuse eth conversion because we can't set invalid bytecode to callData in ethereum - // transaction + trying to delete immutable contract - createDefaultContract(tbdContract) - .bytecode(tbdFile) - .hasKnownStatus(FILE_DELETED) - .refusingEthConversion()) - .when(uploadInitCode(CONTRACT), contractCreate(CONTRACT).refusingEthConversion()) - .then( - contractDelete(CONTRACT) - .claimingPermanentRemoval() - .hasPrecheck(PERMANENT_REMOVAL_REQUIRES_SYSTEM_INITIATION), - contractDelete(CONTRACT), - getContractInfo(CONTRACT).has(contractWith().isDeleted())); + return hapiTest( + fileCreate(tbdFile), + fileDelete(tbdFile), + // refuse eth conversion because we can't set invalid bytecode to callData in ethereum + // transaction + trying to delete immutable contract + createDefaultContract(tbdContract) + .bytecode(tbdFile) + .hasKnownStatus(FILE_DELETED) + .refusingEthConversion(), + uploadInitCode(CONTRACT), + contractCreate(CONTRACT).refusingEthConversion(), + contractDelete(CONTRACT) + .claimingPermanentRemoval() + .hasPrecheck(PERMANENT_REMOVAL_REQUIRES_SYSTEM_INITIATION), + contractDelete(CONTRACT), + getContractInfo(CONTRACT).has(contractWith().isDeleted())); } @HapiTest final Stream deleteFailsWithImmutableContract() { - return defaultHapiSpec("DeleteFailsWithImmutableContract") - .given(uploadInitCode(CONTRACT), contractCreate(CONTRACT).omitAdminKey()) - .when() - .then(contractDelete(CONTRACT).hasKnownStatus(MODIFYING_IMMUTABLE_CONTRACT)); + return hapiTest( + uploadInitCode(CONTRACT), + contractCreate(CONTRACT).omitAdminKey(), + contractDelete(CONTRACT).hasKnownStatus(MODIFYING_IMMUTABLE_CONTRACT)); } @HapiTest final Stream deleteTransfersToAccount() { - return defaultHapiSpec("DeleteTransfersToAccount") - .given( - cryptoCreate(RECEIVER_CONTRACT_NAME).balance(0L), - uploadInitCode(PAYABLE_CONSTRUCTOR), - contractCreate(PAYABLE_CONSTRUCTOR) - // Refusing ethereum create conversion, because we get INVALID_SIGNATURE upon - // tokenAssociate, - // since we have CONTRACT_ID key - .refusingEthConversion() - .balance(1L)) - .when(contractDelete(PAYABLE_CONSTRUCTOR).transferAccount(RECEIVER_CONTRACT_NAME)) - .then(getAccountBalance(RECEIVER_CONTRACT_NAME).hasTinyBars(1L)); + return hapiTest( + cryptoCreate(RECEIVER_CONTRACT_NAME).balance(0L), + uploadInitCode(PAYABLE_CONSTRUCTOR), + contractCreate(PAYABLE_CONSTRUCTOR) + // Refusing ethereum create conversion, because we get INVALID_SIGNATURE upon + // tokenAssociate, + // since we have CONTRACT_ID key + .refusingEthConversion() + .balance(1L), + contractDelete(PAYABLE_CONSTRUCTOR).transferAccount(RECEIVER_CONTRACT_NAME), + getAccountBalance(RECEIVER_CONTRACT_NAME).hasTinyBars(1L)); } @HapiTest final Stream deleteTransfersToContract() { final var suffix = "Receiver"; - return defaultHapiSpec("DeleteTransfersToContract") - .given( - uploadInitCode(PAYABLE_CONSTRUCTOR), - contractCreate(PAYABLE_CONSTRUCTOR) - // Refusing ethereum create conversion, because we get INVALID_SIGNATURE upon - // tokenAssociate, - // since we have CONTRACT_ID key - .refusingEthConversion() - .balance(0L), - contractCustomCreate(PAYABLE_CONSTRUCTOR, suffix).balance(1L)) - .when(contractDelete(PAYABLE_CONSTRUCTOR).transferContract(PAYABLE_CONSTRUCTOR + suffix)) - .then(getAccountBalance(PAYABLE_CONSTRUCTOR + suffix).hasTinyBars(1L)); + return hapiTest( + uploadInitCode(PAYABLE_CONSTRUCTOR), + contractCreate(PAYABLE_CONSTRUCTOR) + // Refusing ethereum create conversion, because we get INVALID_SIGNATURE upon + // tokenAssociate, + // since we have CONTRACT_ID key + .refusingEthConversion() + .balance(0L), + contractCustomCreate(PAYABLE_CONSTRUCTOR, suffix).balance(1L), + contractDelete(PAYABLE_CONSTRUCTOR).transferContract(PAYABLE_CONSTRUCTOR + suffix), + getAccountBalance(PAYABLE_CONSTRUCTOR + suffix).hasTinyBars(1L)); } @HapiTest final Stream localCallToDeletedContract() { - return defaultHapiSpec("LocalCallToDeletedContract") + return hapiTest( // refuse eth conversion because MODIFYING_IMMUTABLE_CONTRACT - .given( - uploadInitCode(SIMPLE_STORAGE_CONTRACT), - contractCreate(SIMPLE_STORAGE_CONTRACT).refusingEthConversion()) - .when( - contractCallLocal(SIMPLE_STORAGE_CONTRACT, "get") - .hasCostAnswerPrecheck(OK) - .has(resultWith().contractCallResult(() -> Bytes32.fromHexString("0x0F"))), - contractDelete(SIMPLE_STORAGE_CONTRACT)) - .then(contractCallLocal(SIMPLE_STORAGE_CONTRACT, "get") + uploadInitCode(SIMPLE_STORAGE_CONTRACT), + contractCreate(SIMPLE_STORAGE_CONTRACT).refusingEthConversion(), + contractCallLocal(SIMPLE_STORAGE_CONTRACT, "get") + .hasCostAnswerPrecheck(OK) + .has(resultWith().contractCallResult(() -> Bytes32.fromHexString("0x0F"))), + contractDelete(SIMPLE_STORAGE_CONTRACT), + contractCallLocal(SIMPLE_STORAGE_CONTRACT, "get") .hasCostAnswerPrecheck(OK) .has(resultWith().contractCallResult(() -> Bytes.EMPTY))); } diff --git a/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/hapi/ContractGetBytecodeSuite.java b/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/hapi/ContractGetBytecodeSuite.java index 18a48a062910..21f4f1564136 100644 --- a/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/hapi/ContractGetBytecodeSuite.java +++ b/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/hapi/ContractGetBytecodeSuite.java @@ -17,7 +17,7 @@ package com.hedera.services.bdd.suites.contract.hapi; import static com.hedera.services.bdd.junit.TestTags.SMART_CONTRACT; -import static com.hedera.services.bdd.spec.HapiSpec.defaultHapiSpec; +import static com.hedera.services.bdd.spec.HapiSpec.hapiTest; import static com.hedera.services.bdd.spec.assertions.AccountInfoAsserts.approxChangeFromSnapshot; import static com.hedera.services.bdd.spec.queries.QueryVerbs.getAccountBalance; import static com.hedera.services.bdd.spec.queries.QueryVerbs.getContractBytecode; @@ -39,7 +39,6 @@ import com.google.common.io.Files; import com.hedera.services.bdd.junit.HapiTest; -import com.hedera.services.bdd.spec.HapiSpec; import com.hedera.services.bdd.spec.HapiSpecSetup; import com.hederahashgraph.api.proto.java.ResponseCodeEnum; import java.io.File; @@ -63,12 +62,10 @@ public class ContractGetBytecodeSuite { @HapiTest final Stream idVariantsTreatedAsExpected() { final var contract = "Multipurpose"; - return defaultHapiSpec("idVariantsTreatedAsExpected") - .given( - uploadInitCode(contract), - contractCreate(contract).entityMemo(MEMO).autoRenewSecs(6999999L)) - .when() - .then(sendModified(withSuccessivelyVariedQueryIds(), () -> getContractBytecode(contract))); + return hapiTest( + uploadInitCode(contract), + contractCreate(contract).entityMemo(MEMO).autoRenewSecs(6999999L), + sendModified(withSuccessivelyVariedQueryIds(), () -> getContractBytecode(contract))); } @HapiTest @@ -76,63 +73,53 @@ final Stream getByteCodeWorks() { final var contract = "EmptyConstructor"; final var canonicalUsdFee = 0.05; final var canonicalQueryFeeAtActiveRate = new AtomicLong(); - return HapiSpec.defaultHapiSpec("GetByteCodeWorks") - .given( - cryptoCreate(CIVILIAN_PAYER).balance(ONE_HUNDRED_HBARS), - uploadInitCode(contract), - contractCreate(contract)) - .when(balanceSnapshot("beforeQuery", CIVILIAN_PAYER)) - .then( - withOpContext((spec, opLog) -> { - final var getBytecode = getContractBytecode(contract) - .payingWith(CIVILIAN_PAYER) - .saveResultTo("contractByteCode") - .exposingBytecodeTo(bytes -> { - canonicalQueryFeeAtActiveRate.set( - spec.ratesProvider().toTbWithActiveRates((long) - (canonicalUsdFee * 100 * TINY_PARTS_PER_WHOLE))); - log.info( - "Canoncal tinybar cost at active rate: {}", - canonicalQueryFeeAtActiveRate.get()); - }); - allRunFor(spec, getBytecode); + return hapiTest( + cryptoCreate(CIVILIAN_PAYER).balance(ONE_HUNDRED_HBARS), + uploadInitCode(contract), + contractCreate(contract), + balanceSnapshot("beforeQuery", CIVILIAN_PAYER), + withOpContext((spec, opLog) -> { + final var getBytecode = getContractBytecode(contract) + .payingWith(CIVILIAN_PAYER) + .saveResultTo("contractByteCode") + .exposingBytecodeTo(bytes -> { + canonicalQueryFeeAtActiveRate.set(spec.ratesProvider() + .toTbWithActiveRates((long) (canonicalUsdFee * 100 * TINY_PARTS_PER_WHOLE))); + log.info( + "Canoncal tinybar cost at active rate: {}", + canonicalQueryFeeAtActiveRate.get()); + }); + allRunFor(spec, getBytecode); - @SuppressWarnings("UnstableApiUsage") - final var originalBytecode = - Hex.decode(Files.toByteArray(new File(getResourcePath(contract, ".bin")))); - final var actualBytecode = spec.registry().getBytes("contractByteCode"); - // The original bytecode is modified on deployment - final var expectedBytecode = - Arrays.copyOfRange(originalBytecode, 29, originalBytecode.length); - Assertions.assertArrayEquals(expectedBytecode, actualBytecode); - }), - // Wait for the query payment transaction to be handled - sleepFor(5_000), - sourcing(() -> getAccountBalance(CIVILIAN_PAYER) - .hasTinyBars( - // Just sanity-check a fee within 50% of the canonical fee to be safe - approxChangeFromSnapshot( - "beforeQuery", - -canonicalQueryFeeAtActiveRate.get(), - canonicalQueryFeeAtActiveRate.get() / 2)))); + @SuppressWarnings("UnstableApiUsage") + final var originalBytecode = + Hex.decode(Files.toByteArray(new File(getResourcePath(contract, ".bin")))); + final var actualBytecode = spec.registry().getBytes("contractByteCode"); + // The original bytecode is modified on deployment + final var expectedBytecode = Arrays.copyOfRange(originalBytecode, 29, originalBytecode.length); + Assertions.assertArrayEquals(expectedBytecode, actualBytecode); + }), + // Wait for the query payment transaction to be handled + sleepFor(5_000), + sourcing(() -> getAccountBalance(CIVILIAN_PAYER) + .hasTinyBars( + // Just sanity-check a fee within 50% of the canonical fee to be safe + approxChangeFromSnapshot( + "beforeQuery", + -canonicalQueryFeeAtActiveRate.get(), + canonicalQueryFeeAtActiveRate.get() / 2)))); } @HapiTest final Stream invalidContractFromCostAnswer() { - return defaultHapiSpec("InvalidContractFromCostAnswer") - .given() - .when() - .then(getContractBytecode(NON_EXISTING_CONTRACT) - .hasCostAnswerPrecheck(ResponseCodeEnum.INVALID_CONTRACT_ID)); + return hapiTest( + getContractBytecode(NON_EXISTING_CONTRACT).hasCostAnswerPrecheck(ResponseCodeEnum.INVALID_CONTRACT_ID)); } @HapiTest final Stream invalidContractFromAnswerOnly() { - return defaultHapiSpec("InvalidContractFromAnswerOnly") - .given() - .when() - .then(getContractBytecode(NON_EXISTING_CONTRACT) - .nodePayment(27_159_182L) - .hasAnswerOnlyPrecheck(ResponseCodeEnum.INVALID_CONTRACT_ID)); + return hapiTest(getContractBytecode(NON_EXISTING_CONTRACT) + .nodePayment(27_159_182L) + .hasAnswerOnlyPrecheck(ResponseCodeEnum.INVALID_CONTRACT_ID)); } } diff --git a/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/hapi/ContractGetInfoSuite.java b/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/hapi/ContractGetInfoSuite.java index 3c8d99209090..1b1243d83ac9 100644 --- a/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/hapi/ContractGetInfoSuite.java +++ b/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/hapi/ContractGetInfoSuite.java @@ -17,7 +17,6 @@ package com.hedera.services.bdd.suites.contract.hapi; import static com.hedera.services.bdd.junit.TestTags.SMART_CONTRACT; -import static com.hedera.services.bdd.spec.HapiSpec.defaultHapiSpec; import static com.hedera.services.bdd.spec.HapiSpec.hapiTest; import static com.hedera.services.bdd.spec.assertions.AccountInfoAsserts.approxChangeFromSnapshot; import static com.hedera.services.bdd.spec.assertions.ContractInfoAsserts.contractWith; @@ -55,12 +54,10 @@ public class ContractGetInfoSuite { @HapiTest final Stream idVariantsTreatedAsExpected() { final var contract = "Multipurpose"; - return defaultHapiSpec("idVariantsTreatedAsExpected") - .given( - uploadInitCode(contract), - contractCreate(contract).entityMemo(MEMO).autoRenewSecs(6999999L)) - .when() - .then(sendModified(withSuccessivelyVariedQueryIds(), () -> getContractInfo(contract))); + return hapiTest( + uploadInitCode(contract), + contractCreate(contract).entityMemo(MEMO).autoRenewSecs(6999999L), + sendModified(withSuccessivelyVariedQueryIds(), () -> getContractInfo(contract))); } @HapiTest @@ -101,20 +98,14 @@ final Stream getInfoWorks() { @HapiTest final Stream invalidContractFromCostAnswer() { - return defaultHapiSpec("InvalidContractFromCostAnswer") - .given() - .when() - .then(getContractInfo(NON_EXISTING_CONTRACT) - .hasCostAnswerPrecheck(ResponseCodeEnum.INVALID_CONTRACT_ID)); + return hapiTest( + getContractInfo(NON_EXISTING_CONTRACT).hasCostAnswerPrecheck(ResponseCodeEnum.INVALID_CONTRACT_ID)); } @HapiTest final Stream invalidContractFromAnswerOnly() { - return defaultHapiSpec("InvalidContractFromAnswerOnly") - .given() - .when() - .then(getContractInfo(NON_EXISTING_CONTRACT) - .nodePayment(27_159_182L) - .hasAnswerOnlyPrecheck(ResponseCodeEnum.INVALID_CONTRACT_ID)); + return hapiTest(getContractInfo(NON_EXISTING_CONTRACT) + .nodePayment(27_159_182L) + .hasAnswerOnlyPrecheck(ResponseCodeEnum.INVALID_CONTRACT_ID)); } } diff --git a/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/hapi/ContractStateSuite.java b/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/hapi/ContractStateSuite.java index cf70d9231b8e..c606c5a75cc9 100644 --- a/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/hapi/ContractStateSuite.java +++ b/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/hapi/ContractStateSuite.java @@ -17,13 +17,13 @@ package com.hedera.services.bdd.suites.contract.hapi; import static com.hedera.services.bdd.junit.TestTags.SMART_CONTRACT; -import static com.hedera.services.bdd.spec.HapiSpec.defaultHapiSpec; import static com.hedera.services.bdd.spec.HapiSpec.hapiTest; import static com.hedera.services.bdd.spec.transactions.TxnVerbs.contractCall; import static com.hedera.services.bdd.spec.transactions.TxnVerbs.contractCreate; import static com.hedera.services.bdd.spec.transactions.TxnVerbs.uploadInitCode; import static com.hedera.services.bdd.spec.transactions.contract.HapiParserUtil.asHeadlongAddress; import static com.hedera.services.bdd.spec.utilops.UtilVerbs.validateAnyLogAfter; +import static com.hedera.services.bdd.suites.HapiSuite.flattened; import static java.lang.Integer.MAX_VALUE; import com.esaulpaugh.headlong.abi.Address; @@ -80,9 +80,10 @@ final Stream stateChangesSpec() { Map.entry("Int128", BigInteger.valueOf(5)), Map.entry("Int256", BigInteger.valueOf(6))); - return defaultHapiSpec("stateChangesSpec") - .given(uploadInitCode(CONTRACT), contractCreate(CONTRACT)) - .when(IntStream.range(0, iterations) + return hapiTest(flattened( + uploadInitCode(CONTRACT), + contractCreate(CONTRACT), + IntStream.range(0, iterations) .boxed() .flatMap(i -> Stream.of( Stream.of(contractCall(CONTRACT, "setVarBool", RANDOM.nextBoolean())), @@ -98,8 +99,7 @@ final Stream stateChangesSpec() { randomSetAndDeleteString(), randomSetAndDeleteStruct()) .flatMap(s -> s)) - .toArray(HapiSpecOperation[]::new)) - .then(); + .toArray(HapiSpecOperation[]::new))); } private Stream randomSetAndDeleteVarInt() { diff --git a/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/hapi/ContractUpdateSuite.java b/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/hapi/ContractUpdateSuite.java index 407fc2c50f5a..7640674517b1 100644 --- a/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/hapi/ContractUpdateSuite.java +++ b/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/hapi/ContractUpdateSuite.java @@ -17,7 +17,6 @@ package com.hedera.services.bdd.suites.contract.hapi; import static com.hedera.services.bdd.junit.TestTags.SMART_CONTRACT; -import static com.hedera.services.bdd.spec.HapiSpec.defaultHapiSpec; import static com.hedera.services.bdd.spec.HapiSpec.hapiTest; import static com.hedera.services.bdd.spec.assertions.ContractFnResultAsserts.isLiteralResult; import static com.hedera.services.bdd.spec.assertions.ContractFnResultAsserts.resultWith; @@ -53,6 +52,7 @@ import static com.hedera.services.bdd.suites.HapiSuite.ONE_HUNDRED_HBARS; import static com.hedera.services.bdd.suites.HapiSuite.THREE_MONTHS_IN_SECONDS; import static com.hedera.services.bdd.suites.HapiSuite.ZERO_BYTE_MEMO; +import static com.hedera.services.bdd.suites.HapiSuite.flattened; import static com.hedera.services.bdd.suites.contract.Utils.FunctionType.FUNCTION; import static com.hedera.services.bdd.suites.contract.Utils.asAddress; import static com.hedera.services.bdd.suites.contract.Utils.captureChildCreate2MetaFor; @@ -98,33 +98,29 @@ public class ContractUpdateSuite { @HapiTest final Stream updateMaxAutomaticAssociationsAndRequireKey() { - return defaultHapiSpec("updateMaxAutomaticAssociationsAndRequireKey") - .given( - newKeyNamed(ADMIN_KEY), - uploadInitCode(CONTRACT), - contractCreate(CONTRACT).adminKey(ADMIN_KEY)) - .when( - contractUpdate(CONTRACT).newMaxAutomaticAssociations(20).signedBy(DEFAULT_PAYER, ADMIN_KEY), - contractUpdate(CONTRACT).newMaxAutomaticAssociations(20).signedBy(DEFAULT_PAYER, ADMIN_KEY), - doWithStartupConfigNow("entities.maxLifetime", (value, now) -> contractUpdate(CONTRACT) - .newMaxAutomaticAssociations(20) - .newExpirySecs(now.getEpochSecond() + Long.parseLong(value) - 12345L) - .signedBy(DEFAULT_PAYER) - .hasKnownStatus(INVALID_SIGNATURE))) - .then(getContractInfo(CONTRACT).has(contractWith().maxAutoAssociations(20))); + return hapiTest( + newKeyNamed(ADMIN_KEY), + uploadInitCode(CONTRACT), + contractCreate(CONTRACT).adminKey(ADMIN_KEY), + contractUpdate(CONTRACT).newMaxAutomaticAssociations(20).signedBy(DEFAULT_PAYER, ADMIN_KEY), + contractUpdate(CONTRACT).newMaxAutomaticAssociations(20).signedBy(DEFAULT_PAYER, ADMIN_KEY), + doWithStartupConfigNow("entities.maxLifetime", (value, now) -> contractUpdate(CONTRACT) + .newMaxAutomaticAssociations(20) + .newExpirySecs(now.getEpochSecond() + Long.parseLong(value) - 12345L) + .signedBy(DEFAULT_PAYER) + .hasKnownStatus(INVALID_SIGNATURE)), + getContractInfo(CONTRACT).has(contractWith().maxAutoAssociations(20))); } @HapiTest final Stream idVariantsTreatedAsExpected() { - return defaultHapiSpec("idVariantsTreatedAsExpected") - .given( - newKeyNamed(ADMIN_KEY), - cryptoCreate("a"), - cryptoCreate("b"), - uploadInitCode(CONTRACT), - contractCreate(CONTRACT).autoRenewAccountId("a").stakedAccountId("b")) - .when() - .then(submitModified( + return hapiTest( + newKeyNamed(ADMIN_KEY), + cryptoCreate("a"), + cryptoCreate("b"), + uploadInitCode(CONTRACT), + contractCreate(CONTRACT).autoRenewAccountId("a").stakedAccountId("b"), + submitModified( withSuccessivelyVariedBodyIds(), () -> contractUpdate(CONTRACT).newAutoRenewAccount("b").newStakedAccountId("a"))); } @@ -556,10 +552,10 @@ final Stream playGame() { asAddress(spec.registry().getAccountID("Player13"))) })))))); - return defaultHapiSpec("playGame") - .given(given.toArray(HapiSpecOperation[]::new)) - .when(when.toArray(HapiSpecOperation[]::new)) - .then(then.toArray(HapiSpecOperation[]::new)); + return hapiTest(flattened( + given.toArray(HapiSpecOperation[]::new), + when.toArray(HapiSpecOperation[]::new), + then.toArray(HapiSpecOperation[]::new))); } @HapiTest diff --git a/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/opcodes/Create2OperationSuite.java b/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/opcodes/Create2OperationSuite.java index aa0734755e34..3d6217024930 100644 --- a/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/opcodes/Create2OperationSuite.java +++ b/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/opcodes/Create2OperationSuite.java @@ -25,7 +25,6 @@ import static com.hedera.services.bdd.spec.HapiPropertySource.contractIdFromHexedMirrorAddress; import static com.hedera.services.bdd.spec.HapiPropertySource.explicitBytesOf; import static com.hedera.services.bdd.spec.HapiPropertySource.literalIdFromHexedMirrorAddress; -import static com.hedera.services.bdd.spec.HapiSpec.defaultHapiSpec; import static com.hedera.services.bdd.spec.HapiSpec.hapiTest; import static com.hedera.services.bdd.spec.assertions.AccountInfoAsserts.accountWith; import static com.hedera.services.bdd.spec.assertions.AssertUtils.inOrder; @@ -784,62 +783,58 @@ final Stream canDeleteViaAlias() { final var salt = unhex(SALT); final var otherSalt = unhex("aabbccddee330011aabbccddee330011aabbccddee330011aabbccddee330011"); - return defaultHapiSpec("CanDeleteViaAlias") - .given( - newKeyNamed(adminKey), - uploadInitCode(contract), - contractCreate(contract).adminKey(adminKey).payingWith(GENESIS), - contractCall(contract, "buildCreator", salt) - .payingWith(GENESIS) - .gas(4_000_000L) - .via(creation2), - captureOneChildCreate2MetaFor( - "Salting creator", creation2, saltingCreatorMirrorAddr, saltingCreatorAliasAddr), - withOpContext((spec, opLog) -> saltingCreatorLiteralId.set( - asContractString(contractIdFromHexedMirrorAddress(saltingCreatorMirrorAddr.get())))), - // https://github.com/hashgraph/hedera-services/issues/2867 (can't - // re-create2 after selfdestruct) - sourcing(() -> contractCallWithFunctionAbi( - saltingCreatorAliasAddr.get(), - getABIFor(FUNCTION, "createAndRecreateTest", saltingCreator), - otherSalt) - .payingWith(GENESIS) - .gas(2_000_000L) - .hasKnownStatus(CONTRACT_REVERT_EXECUTED))) - .when( - sourcing(() -> contractUpdate(saltingCreatorAliasAddr.get()) - .signedBy(DEFAULT_PAYER, adminKey) - .memo("That's why you always leave a note")), - sourcing(() -> contractCallLocalWithFunctionAbi( - saltingCreatorAliasAddr.get(), - getABIFor(FUNCTION, "whatTheFoo", saltingCreator)) - .has(resultWith() - .resultThruAbi( - getABIFor(FUNCTION, "whatTheFoo", saltingCreator), - isLiteralResult(new Object[] {BigInteger.valueOf(42)})))), - sourcing(() -> contractDelete(saltingCreatorAliasAddr.get()) - .signedBy(DEFAULT_PAYER, adminKey) - .transferContract(saltingCreatorMirrorAddr.get()) - .hasKnownStatus(OBTAINER_SAME_CONTRACT_ID)), - sourcing(() -> contractDelete(saltingCreatorMirrorAddr.get()) - .signedBy(DEFAULT_PAYER, adminKey) - .transferContract(saltingCreatorAliasAddr.get()) - .hasKnownStatus(OBTAINER_SAME_CONTRACT_ID))) - .then( - sourcing(() -> getContractInfo(saltingCreatorMirrorAddr.get()) - .has(contractWith().addressOrAlias(saltingCreatorAliasAddr.get()))), - sourcing(() -> contractDelete(saltingCreatorAliasAddr.get()) - .signedBy(DEFAULT_PAYER, adminKey) - .transferAccount(FUNDING) - .via(deletion)), - sourcing(() -> getTxnRecord(deletion) - .hasPriority(recordWith().targetedContractId(saltingCreatorLiteralId.get()))), - sourcing(() -> contractDelete(saltingCreatorMirrorAddr.get()) - .signedBy(DEFAULT_PAYER, adminKey) - .transferAccount(FUNDING) - .hasPrecheck(CONTRACT_DELETED)), - sourcing(() -> getContractInfo(saltingCreatorMirrorAddr.get()) - .has(contractWith().addressOrAlias(saltingCreatorMirrorAddr.get())))); + return hapiTest( + newKeyNamed(adminKey), + uploadInitCode(contract), + contractCreate(contract).adminKey(adminKey).payingWith(GENESIS), + contractCall(contract, "buildCreator", salt) + .payingWith(GENESIS) + .gas(4_000_000L) + .via(creation2), + captureOneChildCreate2MetaFor( + "Salting creator", creation2, saltingCreatorMirrorAddr, saltingCreatorAliasAddr), + withOpContext((spec, opLog) -> saltingCreatorLiteralId.set( + asContractString(contractIdFromHexedMirrorAddress(saltingCreatorMirrorAddr.get())))), + // https://github.com/hashgraph/hedera-services/issues/2867 (can't + // re-create2 after selfdestruct) + sourcing(() -> contractCallWithFunctionAbi( + saltingCreatorAliasAddr.get(), + getABIFor(FUNCTION, "createAndRecreateTest", saltingCreator), + otherSalt) + .payingWith(GENESIS) + .gas(2_000_000L) + .hasKnownStatus(CONTRACT_REVERT_EXECUTED)), + sourcing(() -> contractUpdate(saltingCreatorAliasAddr.get()) + .signedBy(DEFAULT_PAYER, adminKey) + .memo("That's why you always leave a note")), + sourcing(() -> contractCallLocalWithFunctionAbi( + saltingCreatorAliasAddr.get(), getABIFor(FUNCTION, "whatTheFoo", saltingCreator)) + .has(resultWith() + .resultThruAbi( + getABIFor(FUNCTION, "whatTheFoo", saltingCreator), + isLiteralResult(new Object[] {BigInteger.valueOf(42)})))), + sourcing(() -> contractDelete(saltingCreatorAliasAddr.get()) + .signedBy(DEFAULT_PAYER, adminKey) + .transferContract(saltingCreatorMirrorAddr.get()) + .hasKnownStatus(OBTAINER_SAME_CONTRACT_ID)), + sourcing(() -> contractDelete(saltingCreatorMirrorAddr.get()) + .signedBy(DEFAULT_PAYER, adminKey) + .transferContract(saltingCreatorAliasAddr.get()) + .hasKnownStatus(OBTAINER_SAME_CONTRACT_ID)), + sourcing(() -> getContractInfo(saltingCreatorMirrorAddr.get()) + .has(contractWith().addressOrAlias(saltingCreatorAliasAddr.get()))), + sourcing(() -> contractDelete(saltingCreatorAliasAddr.get()) + .signedBy(DEFAULT_PAYER, adminKey) + .transferAccount(FUNDING) + .via(deletion)), + sourcing(() -> getTxnRecord(deletion) + .hasPriority(recordWith().targetedContractId(saltingCreatorLiteralId.get()))), + sourcing(() -> contractDelete(saltingCreatorMirrorAddr.get()) + .signedBy(DEFAULT_PAYER, adminKey) + .transferAccount(FUNDING) + .hasPrecheck(CONTRACT_DELETED)), + sourcing(() -> getContractInfo(saltingCreatorMirrorAddr.get()) + .has(contractWith().addressOrAlias(saltingCreatorMirrorAddr.get())))); } @SuppressWarnings("java:S5669") @@ -919,47 +914,42 @@ final Stream priorityAddressIsCreate2ForStaticHapiCalls() { final var salt = unhex(SALT); - return defaultHapiSpec("PriorityAddressIsCreate2ForStaticHapiCalls") - .given( - uploadInitCode(contract), - contractCreate(contract).payingWith(GENESIS), - contractCall(contract, "createReturner", salt) - .payingWith(GENESIS) - .gas(4_000_000L) - .via(CREATE_2_TXN), - captureOneChildCreate2MetaFor(RETURNER, CREATE_2_TXN, mirrorAddr, aliasAddr)) - .when( - sourcing(() -> contractCallLocalWithFunctionAbi( - mirrorAddr.get(), getABIFor(FUNCTION, "returnThis", RETURNER)) - .payingWith(GENESIS) - .exposingTypedResultsTo(results -> { - LOG.info(RETURNER_REPORTED_LOG_MESSAGE, results); - staticCallMirrorAns.set((BigInteger) results[0]); - })), - sourcing(() -> contractCallLocalWithFunctionAbi( - aliasAddr.get(), getABIFor(FUNCTION, "returnThis", RETURNER)) - .payingWith(GENESIS) - .exposingTypedResultsTo(results -> { - LOG.info("Returner reported {} when" + " called with alias" + " address", results); - staticCallAliasAns.set((BigInteger) results[0]); - }))) - .then( - withOpContext((spec, opLog) -> { - assertEquals( - staticCallAliasAns.get(), - staticCallMirrorAns.get(), - "Static call with mirror address should be same as call" + " with alias"); - assertTrue( - aliasAddr - .get() - .endsWith(staticCallAliasAns.get().toString(16)), - "Alias should get priority over mirror address"); - }), - sourcing(() -> contractCallWithFunctionAbi( - aliasAddr.get(), getABIFor(FUNCTION, "createPlaceholder", RETURNER)) - .gas(4_000_000L) - .payingWith(GENESIS) - .via(CREATION))); + return hapiTest( + uploadInitCode(contract), + contractCreate(contract).payingWith(GENESIS), + contractCall(contract, "createReturner", salt) + .payingWith(GENESIS) + .gas(4_000_000L) + .via(CREATE_2_TXN), + captureOneChildCreate2MetaFor(RETURNER, CREATE_2_TXN, mirrorAddr, aliasAddr), + sourcing(() -> contractCallLocalWithFunctionAbi( + mirrorAddr.get(), getABIFor(FUNCTION, "returnThis", RETURNER)) + .payingWith(GENESIS) + .exposingTypedResultsTo(results -> { + LOG.info(RETURNER_REPORTED_LOG_MESSAGE, results); + staticCallMirrorAns.set((BigInteger) results[0]); + })), + sourcing(() -> contractCallLocalWithFunctionAbi( + aliasAddr.get(), getABIFor(FUNCTION, "returnThis", RETURNER)) + .payingWith(GENESIS) + .exposingTypedResultsTo(results -> { + LOG.info("Returner reported {} when" + " called with alias" + " address", results); + staticCallAliasAns.set((BigInteger) results[0]); + })), + withOpContext((spec, opLog) -> { + assertEquals( + staticCallAliasAns.get(), + staticCallMirrorAns.get(), + "Static call with mirror address should be same as call" + " with alias"); + assertTrue( + aliasAddr.get().endsWith(staticCallAliasAns.get().toString(16)), + "Alias should get priority over mirror address"); + }), + sourcing(() -> contractCallWithFunctionAbi( + aliasAddr.get(), getABIFor(FUNCTION, "createPlaceholder", RETURNER)) + .gas(4_000_000L) + .payingWith(GENESIS) + .via(CREATION))); } @HapiTest diff --git a/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/opcodes/CreateOperationSuite.java b/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/opcodes/CreateOperationSuite.java index 1e8df45d38c0..a8a60f405fee 100644 --- a/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/opcodes/CreateOperationSuite.java +++ b/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/opcodes/CreateOperationSuite.java @@ -17,7 +17,6 @@ package com.hedera.services.bdd.suites.contract.opcodes; import static com.hedera.services.bdd.junit.TestTags.SMART_CONTRACT; -import static com.hedera.services.bdd.spec.HapiSpec.defaultHapiSpec; import static com.hedera.services.bdd.spec.HapiSpec.hapiTest; import static com.hedera.services.bdd.spec.assertions.AssertUtils.inOrder; import static com.hedera.services.bdd.spec.assertions.ContractFnResultAsserts.resultWith; @@ -147,17 +146,15 @@ final Stream stackedFactoryWorks() { @HapiTest final Stream resetOnFactoryFailureWorks() { - return defaultHapiSpec("ResetOnFactoryFailureWorks") - .given(uploadInitCode(CONTRACT), contractCreate(CONTRACT)) - .when( - contractCall(CONTRACT, "stackedDeploymentFailure") - .hasKnownStatus(ResponseCodeEnum.CONTRACT_REVERT_EXECUTED) - .gas(780_000) - .via("deploymentFailureTxn"), - contractCall(CONTRACT, DEPLOYMENT_SUCCESS_FUNCTION) - .gas(780_000) - .via(DEPLOYMENT_SUCCESS_TXN)) - .then(withOpContext((spec, opLog) -> { + return hapiTest( + uploadInitCode(CONTRACT), + contractCreate(CONTRACT), + contractCall(CONTRACT, "stackedDeploymentFailure") + .hasKnownStatus(ResponseCodeEnum.CONTRACT_REVERT_EXECUTED) + .gas(780_000) + .via("deploymentFailureTxn"), + contractCall(CONTRACT, DEPLOYMENT_SUCCESS_FUNCTION).gas(780_000).via(DEPLOYMENT_SUCCESS_TXN), + withOpContext((spec, opLog) -> { final var revertTxn = getTxnRecord("deploymentFailureTxn"); final var deploymentSuccessTxn = getTxnRecord(DEPLOYMENT_SUCCESS_TXN); final var parentContract = getContractInfo(CONTRACT).saveToRegistry(CONTRACT_INFO); @@ -179,17 +176,15 @@ final Stream resetOnFactoryFailureWorks() { @HapiTest final Stream resetOnFactoryFailureAfterDeploymentWorks() { - return defaultHapiSpec("ResetOnFactoryFailureAfterDeploymentWorks") - .given(uploadInitCode(CONTRACT), contractCreate(CONTRACT)) - .when( - contractCall(CONTRACT, "failureAfterDeploy") - .hasKnownStatus(ResponseCodeEnum.CONTRACT_REVERT_EXECUTED) - .gas(780_000) - .via("failureAfterDeploymentTxn"), - contractCall(CONTRACT, DEPLOYMENT_SUCCESS_FUNCTION) - .gas(780_000) - .via(DEPLOYMENT_SUCCESS_TXN)) - .then(withOpContext((spec, opLog) -> { + return hapiTest( + uploadInitCode(CONTRACT), + contractCreate(CONTRACT), + contractCall(CONTRACT, "failureAfterDeploy") + .hasKnownStatus(ResponseCodeEnum.CONTRACT_REVERT_EXECUTED) + .gas(780_000) + .via("failureAfterDeploymentTxn"), + contractCall(CONTRACT, DEPLOYMENT_SUCCESS_FUNCTION).gas(780_000).via(DEPLOYMENT_SUCCESS_TXN), + withOpContext((spec, opLog) -> { final var revertTxn = getTxnRecord("failureAfterDeploymentTxn"); final var deploymentSuccessTxn = getTxnRecord(DEPLOYMENT_SUCCESS_TXN); final var parentContract = getContractInfo(CONTRACT).saveToRegistry(CONTRACT_INFO); @@ -211,17 +206,15 @@ final Stream resetOnFactoryFailureAfterDeploymentWorks() { @HapiTest final Stream resetOnStackedFactoryFailureWorks() { - return defaultHapiSpec("ResetOnStackedFactoryFailureWorks") - .given(uploadInitCode(CONTRACT), contractCreate(CONTRACT)) - .when( - contractCall(CONTRACT, "stackedDeploymentFailure") - .hasKnownStatus(ResponseCodeEnum.CONTRACT_REVERT_EXECUTED) - .gas(780_000) - .via("stackedDeploymentFailureTxn"), - contractCall(CONTRACT, DEPLOYMENT_SUCCESS_FUNCTION) - .gas(780_000) - .via(DEPLOYMENT_SUCCESS_TXN)) - .then(withOpContext((spec, opLog) -> { + return hapiTest( + uploadInitCode(CONTRACT), + contractCreate(CONTRACT), + contractCall(CONTRACT, "stackedDeploymentFailure") + .hasKnownStatus(ResponseCodeEnum.CONTRACT_REVERT_EXECUTED) + .gas(780_000) + .via("stackedDeploymentFailureTxn"), + contractCall(CONTRACT, DEPLOYMENT_SUCCESS_FUNCTION).gas(780_000).via(DEPLOYMENT_SUCCESS_TXN), + withOpContext((spec, opLog) -> { final var revertTxn = getTxnRecord("stackedDeploymentFailureTxn"); final var deploymentSuccessTxn = getTxnRecord(DEPLOYMENT_SUCCESS_TXN); final var parentContract = getContractInfo(CONTRACT).saveToRegistry(CONTRACT_INFO); @@ -264,10 +257,10 @@ final Stream childContractStorageWorks() { final var contract = "CreateTrivial"; final var CREATED_TRIVIAL_CONTRACT_RETURNS = 7; - return defaultHapiSpec("childContractStorageWorks") - .given(uploadInitCode(contract)) - .when(contractCreate(contract).via("firstContractTxn")) - .then(assertionsHold((spec, ctxLog) -> { + return hapiTest( + uploadInitCode(contract), + contractCreate(contract).via("firstContractTxn"), + assertionsHold((spec, ctxLog) -> { final var subop1 = contractCall(contract, "create").gas(785_000).via("createContractTxn"); diff --git a/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/opcodes/DelegateCallOperationSuite.java b/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/opcodes/DelegateCallOperationSuite.java index e0f5574d04ab..5cbf138ecac5 100644 --- a/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/opcodes/DelegateCallOperationSuite.java +++ b/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/opcodes/DelegateCallOperationSuite.java @@ -17,7 +17,7 @@ package com.hedera.services.bdd.suites.contract.opcodes; import static com.hedera.services.bdd.junit.TestTags.SMART_CONTRACT; -import static com.hedera.services.bdd.spec.HapiSpec.defaultHapiSpec; +import static com.hedera.services.bdd.spec.HapiSpec.hapiTest; import static com.hedera.services.bdd.spec.transactions.TxnVerbs.contractCall; import static com.hedera.services.bdd.spec.transactions.TxnVerbs.contractCreate; import static com.hedera.services.bdd.spec.transactions.TxnVerbs.uploadInitCode; @@ -39,21 +39,19 @@ public class DelegateCallOperationSuite { final Stream verifiesExistence() { final var contract = "CallOperationsChecker"; final var INVALID_ADDRESS = "0x0000000000000000000000000000000000123456"; - return defaultHapiSpec("VerifiesExistence") - .given(uploadInitCode(contract), contractCreate(contract)) - .when() - .then( - contractCall(contract, "delegateCall", asHeadlongAddress(INVALID_ADDRESS)) - .hasKnownStatus(SUCCESS), - withOpContext((spec, opLog) -> { - final var id = spec.registry().getAccountID(DEFAULT_PAYER); - final var solidityAddress = HapiPropertySource.asHexedSolidityAddress(id); + return hapiTest( + uploadInitCode(contract), + contractCreate(contract), + contractCall(contract, "delegateCall", asHeadlongAddress(INVALID_ADDRESS)) + .hasKnownStatus(SUCCESS), + withOpContext((spec, opLog) -> { + final var id = spec.registry().getAccountID(DEFAULT_PAYER); + final var solidityAddress = HapiPropertySource.asHexedSolidityAddress(id); - final var contractCall = contractCall( - contract, "delegateCall", asHeadlongAddress(solidityAddress)) - .hasKnownStatus(SUCCESS); + final var contractCall = contractCall(contract, "delegateCall", asHeadlongAddress(solidityAddress)) + .hasKnownStatus(SUCCESS); - allRunFor(spec, contractCall); - })); + allRunFor(spec, contractCall); + })); } } diff --git a/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/opcodes/GlobalPropertiesSuite.java b/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/opcodes/GlobalPropertiesSuite.java index bce66cf1aeee..b0010f383413 100644 --- a/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/opcodes/GlobalPropertiesSuite.java +++ b/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/opcodes/GlobalPropertiesSuite.java @@ -17,7 +17,7 @@ package com.hedera.services.bdd.suites.contract.opcodes; import static com.hedera.services.bdd.junit.TestTags.SMART_CONTRACT; -import static com.hedera.services.bdd.spec.HapiSpec.defaultHapiSpec; +import static com.hedera.services.bdd.spec.HapiSpec.hapiTest; import static com.hedera.services.bdd.spec.assertions.ContractFnResultAsserts.*; import static com.hedera.services.bdd.spec.assertions.TransactionRecordAsserts.recordWith; import static com.hedera.services.bdd.spec.queries.QueryVerbs.contractCallLocal; @@ -55,55 +55,55 @@ final Stream chainIdWorks() { final var defaultChainId = BigInteger.valueOf(295L); final var devChainId = BigInteger.valueOf(298L); final Set acceptableChainIds = Set.of(devChainId, defaultChainId); - return defaultHapiSpec("chainIdWorks") - .given(uploadInitCode(CONTRACT), contractCreate(CONTRACT)) - .when(contractCall(CONTRACT, GET_CHAIN_ID).via("chainId")) - .then( - getTxnRecord("chainId") - .logged() - .hasPriority(recordWith() - .contractCallResult(resultWith() - .resultThruAbi( - getABIFor(FUNCTION, GET_CHAIN_ID, CONTRACT), - isOneOfLiteral(acceptableChainIds)))), - contractCallLocal(CONTRACT, GET_CHAIN_ID) - .nodePayment(1_234_567) - .has(ContractFnResultAsserts.resultWith() + return hapiTest( + uploadInitCode(CONTRACT), + contractCreate(CONTRACT), + contractCall(CONTRACT, GET_CHAIN_ID).via("chainId"), + getTxnRecord("chainId") + .logged() + .hasPriority(recordWith() + .contractCallResult(resultWith() .resultThruAbi( getABIFor(FUNCTION, GET_CHAIN_ID, CONTRACT), - isOneOfLiteral(acceptableChainIds)))); + isOneOfLiteral(acceptableChainIds)))), + contractCallLocal(CONTRACT, GET_CHAIN_ID) + .nodePayment(1_234_567) + .has(ContractFnResultAsserts.resultWith() + .resultThruAbi( + getABIFor(FUNCTION, GET_CHAIN_ID, CONTRACT), + isOneOfLiteral(acceptableChainIds)))); } @HapiTest final Stream baseFeeWorks() { final var expectedBaseFee = BigInteger.valueOf(0); - return defaultHapiSpec("baseFeeWorks") - .given(uploadInitCode(CONTRACT), contractCreate(CONTRACT)) - .when(contractCall(CONTRACT, GET_BASE_FEE).via("baseFee")) - .then( - getTxnRecord("baseFee") - .logged() - .hasPriority(recordWith() - .contractCallResult(resultWith() - .resultThruAbi( - getABIFor(FUNCTION, GET_BASE_FEE, CONTRACT), - isLiteralResult(new Object[] {BigInteger.valueOf(0)})))), - contractCallLocal(CONTRACT, GET_BASE_FEE) - .nodePayment(1_234_567) - .has(ContractFnResultAsserts.resultWith() + return hapiTest( + uploadInitCode(CONTRACT), + contractCreate(CONTRACT), + contractCall(CONTRACT, GET_BASE_FEE).via("baseFee"), + getTxnRecord("baseFee") + .logged() + .hasPriority(recordWith() + .contractCallResult(resultWith() .resultThruAbi( getABIFor(FUNCTION, GET_BASE_FEE, CONTRACT), - ContractFnResultAsserts.isLiteralResult( - new Object[] {expectedBaseFee})))); + isLiteralResult(new Object[] {BigInteger.valueOf(0)})))), + contractCallLocal(CONTRACT, GET_BASE_FEE) + .nodePayment(1_234_567) + .has(ContractFnResultAsserts.resultWith() + .resultThruAbi( + getABIFor(FUNCTION, GET_BASE_FEE, CONTRACT), + ContractFnResultAsserts.isLiteralResult(new Object[] {expectedBaseFee})))); } @SuppressWarnings("java:S5960") @HapiTest final Stream coinbaseWorks() { - return defaultHapiSpec("coinbaseWorks") - .given(uploadInitCode(CONTRACT), contractCreate(CONTRACT)) - .when(contractCall(CONTRACT, "getCoinbase").via("coinbase")) - .then(withOpContext((spec, opLog) -> { + return hapiTest( + uploadInitCode(CONTRACT), + contractCreate(CONTRACT), + contractCall(CONTRACT, "getCoinbase").via("coinbase"), + withOpContext((spec, opLog) -> { final var expectedCoinbase = parsedToByteString(DEFAULT_PROPS.fundingAccount().getAccountNum()); @@ -123,10 +123,10 @@ final Stream coinbaseWorks() { @HapiTest final Stream gasLimitWorks() { - return defaultHapiSpec("gasLimitWorks") - .given(uploadInitCode(CONTRACT), contractCreate(CONTRACT)) - .when() - .then(doSeveralWithStartupConfig("contracts.maxGasPerSec", value -> { + return hapiTest( + uploadInitCode(CONTRACT), + contractCreate(CONTRACT), + doSeveralWithStartupConfig("contracts.maxGasPerSec", value -> { final var gasLimit = Long.parseLong(value); return specOps( contractCall(CONTRACT, GET_GAS_LIMIT) diff --git a/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/precompile/ApproveAllowanceSuite.java b/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/precompile/ApproveAllowanceSuite.java index 48f7dd3fa8d9..0c0d45eb80d4 100644 --- a/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/precompile/ApproveAllowanceSuite.java +++ b/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/precompile/ApproveAllowanceSuite.java @@ -19,7 +19,6 @@ import static com.hedera.services.bdd.junit.TestTags.SMART_CONTRACT; import static com.hedera.services.bdd.spec.HapiPropertySource.asHexedSolidityAddress; import static com.hedera.services.bdd.spec.HapiPropertySource.asSolidityAddress; -import static com.hedera.services.bdd.spec.HapiSpec.defaultHapiSpec; import static com.hedera.services.bdd.spec.HapiSpec.hapiTest; import static com.hedera.services.bdd.spec.assertions.AccountDetailsAsserts.accountDetailsWith; import static com.hedera.services.bdd.spec.assertions.AssertUtils.inOrder; @@ -216,40 +215,37 @@ final Stream htsTokenApproveToInnerContract() { @HapiTest final Stream idVariantsTreatedAsExpected() { - return defaultHapiSpec("idVariantsTreatedAsExpected") - .given( - newKeyNamed("supplyKey"), - cryptoCreate(TOKEN_TREASURY), - cryptoCreate(OWNER).maxAutomaticTokenAssociations(2), - cryptoCreate("delegatingOwner").maxAutomaticTokenAssociations(1), - cryptoCreate(SPENDER)) - .when( - tokenCreate("fungibleToken").initialSupply(123).treasury(TOKEN_TREASURY), - tokenCreate("nonFungibleToken") - .treasury(TOKEN_TREASURY) - .tokenType(NON_FUNGIBLE_UNIQUE) - .initialSupply(0L) - .supplyKey("supplyKey"), - mintToken( - "nonFungibleToken", - List.of( - ByteString.copyFromUtf8("A"), - ByteString.copyFromUtf8("B"), - ByteString.copyFromUtf8("C"))), - cryptoTransfer( - movingUnique("nonFungibleToken", 1L, 2L).between(TOKEN_TREASURY, OWNER), - moving(10, "fungibleToken").between(TOKEN_TREASURY, OWNER)), - cryptoTransfer(movingUnique("nonFungibleToken", 3L).between(TOKEN_TREASURY, "delegatingOwner"))) - .then( - submitModified(withSuccessivelyVariedBodyIds(), () -> cryptoApproveAllowance() - .addNftAllowance("delegatingOwner", "nonFungibleToken", OWNER, true, List.of()) - .signedBy(DEFAULT_PAYER, "delegatingOwner")), - submitModified(withSuccessivelyVariedBodyIds(), () -> cryptoApproveAllowance() - .addNftAllowance(OWNER, "nonFungibleToken", SPENDER, false, List.of(1L)) - .addTokenAllowance(OWNER, "fungibleToken", SPENDER, 1L) - .addDelegatedNftAllowance( - "delegatingOwner", "nonFungibleToken", SPENDER, OWNER, false, List.of(3L)) - .signedBy(DEFAULT_PAYER, OWNER))); + return hapiTest( + newKeyNamed("supplyKey"), + cryptoCreate(TOKEN_TREASURY), + cryptoCreate(OWNER).maxAutomaticTokenAssociations(2), + cryptoCreate("delegatingOwner").maxAutomaticTokenAssociations(1), + cryptoCreate(SPENDER), + tokenCreate("fungibleToken").initialSupply(123).treasury(TOKEN_TREASURY), + tokenCreate("nonFungibleToken") + .treasury(TOKEN_TREASURY) + .tokenType(NON_FUNGIBLE_UNIQUE) + .initialSupply(0L) + .supplyKey("supplyKey"), + mintToken( + "nonFungibleToken", + List.of( + ByteString.copyFromUtf8("A"), + ByteString.copyFromUtf8("B"), + ByteString.copyFromUtf8("C"))), + cryptoTransfer( + movingUnique("nonFungibleToken", 1L, 2L).between(TOKEN_TREASURY, OWNER), + moving(10, "fungibleToken").between(TOKEN_TREASURY, OWNER)), + cryptoTransfer(movingUnique("nonFungibleToken", 3L).between(TOKEN_TREASURY, "delegatingOwner")), + submitModified(withSuccessivelyVariedBodyIds(), () -> cryptoApproveAllowance() + .addNftAllowance("delegatingOwner", "nonFungibleToken", OWNER, true, List.of()) + .signedBy(DEFAULT_PAYER, "delegatingOwner")), + submitModified(withSuccessivelyVariedBodyIds(), () -> cryptoApproveAllowance() + .addNftAllowance(OWNER, "nonFungibleToken", SPENDER, false, List.of(1L)) + .addTokenAllowance(OWNER, "fungibleToken", SPENDER, 1L) + .addDelegatedNftAllowance( + "delegatingOwner", "nonFungibleToken", SPENDER, OWNER, false, List.of(3L)) + .signedBy(DEFAULT_PAYER, OWNER))); } @HapiTest diff --git a/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/precompile/AssociatePrecompileSuite.java b/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/precompile/AssociatePrecompileSuite.java index 165b7213bf21..84a2b567c7c6 100644 --- a/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/precompile/AssociatePrecompileSuite.java +++ b/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/precompile/AssociatePrecompileSuite.java @@ -18,7 +18,6 @@ import static com.hedera.services.bdd.junit.TestTags.SMART_CONTRACT; import static com.hedera.services.bdd.spec.HapiPropertySource.idAsHeadlongAddress; -import static com.hedera.services.bdd.spec.HapiSpec.defaultHapiSpec; import static com.hedera.services.bdd.spec.HapiSpec.hapiTest; import static com.hedera.services.bdd.spec.assertions.ContractFnResultAsserts.resultWith; import static com.hedera.services.bdd.spec.assertions.TransactionRecordAsserts.recordWith; @@ -93,25 +92,27 @@ public class AssociatePrecompileSuite { /* -- HSCS-PREC-27 from HTS Precompile Test Plan -- */ @HapiTest final Stream functionCallWithLessThanFourBytesFailsWithinSingleContractCall() { - return defaultHapiSpec("functionCallWithLessThanFourBytesFailsWithinSingleContractCall") - .given(uploadInitCode(THE_GRACEFULLY_FAILING_CONTRACT), contractCreate(THE_GRACEFULLY_FAILING_CONTRACT)) - .when(contractCall( + return hapiTest( + uploadInitCode(THE_GRACEFULLY_FAILING_CONTRACT), + contractCreate(THE_GRACEFULLY_FAILING_CONTRACT), + contractCall( THE_GRACEFULLY_FAILING_CONTRACT, "performLessThanFourBytesFunctionCall", HapiParserUtil.asHeadlongAddress(ACCOUNT_ADDRESS), HapiParserUtil.asHeadlongAddress(TOKEN_ADDRESS)) .notTryingAsHexedliteral() .via("Function call with less than 4 bytes txn") - .gas(100_000)) - .then(childRecordsCheck("Function call with less than 4 bytes txn", SUCCESS)); + .gas(100_000), + childRecordsCheck("Function call with less than 4 bytes txn", SUCCESS)); } /* -- HSCS-PREC-27 from HTS Precompile Test Plan -- */ @HapiTest final Stream invalidAbiCallGracefullyFailsWithinSingleContractCall() { - return defaultHapiSpec("invalidAbiCallGracefullyFailsWithinSingleContractCall") - .given(uploadInitCode(THE_GRACEFULLY_FAILING_CONTRACT), contractCreate(THE_GRACEFULLY_FAILING_CONTRACT)) - .when(contractCall( + return hapiTest( + uploadInitCode(THE_GRACEFULLY_FAILING_CONTRACT), + contractCreate(THE_GRACEFULLY_FAILING_CONTRACT), + contractCall( THE_GRACEFULLY_FAILING_CONTRACT, "performInvalidlyFormattedFunctionCall", HapiParserUtil.asHeadlongAddress(ACCOUNT_ADDRESS), @@ -120,8 +121,8 @@ final Stream invalidAbiCallGracefullyFailsWithinSingleContractCall( HapiParserUtil.asHeadlongAddress(TOKEN_ADDRESS) }) .notTryingAsHexedliteral() - .via("Invalid Abi Function call txn")) - .then(childRecordsCheck("Invalid Abi Function call txn", SUCCESS)); + .via("Invalid Abi Function call txn"), + childRecordsCheck("Invalid Abi Function call txn", SUCCESS)); } /* -- HSCS-PREC-26 from HTS Precompile Test Plan -- */ @@ -301,27 +302,26 @@ final Stream associateTokensNegativeScenarios() { final var zeroAccountAddress = "zeroAccountAddress"; final var nullTokenArray = "nullTokens"; final var nonExistingTokensInArray = "nonExistingTokensInArray"; - return defaultHapiSpec("associateTokensNegativeScenarios") - .given( - uploadInitCode(NEGATIVE_ASSOCIATIONS_CONTRACT), - contractCreate(NEGATIVE_ASSOCIATIONS_CONTRACT), - cryptoCreate(TOKEN_TREASURY), - tokenCreate(TOKEN) - .tokenType(TokenType.FUNGIBLE_COMMON) - .initialSupply(50L) - .supplyKey(TOKEN_TREASURY) - .adminKey(TOKEN_TREASURY) - .treasury(TOKEN_TREASURY) - .exposingAddressTo(tokenAddress1::set), - tokenCreate(TOKEN1) - .tokenType(TokenType.FUNGIBLE_COMMON) - .initialSupply(50L) - .supplyKey(TOKEN_TREASURY) - .adminKey(TOKEN_TREASURY) - .treasury(TOKEN_TREASURY) - .exposingAddressTo(tokenAddress2::set), - cryptoCreate(ACCOUNT).exposingCreatedIdTo(id -> accountAddress.set(idAsHeadlongAddress(id)))) - .when(withOpContext((spec, custom) -> allRunFor( + return hapiTest( + uploadInitCode(NEGATIVE_ASSOCIATIONS_CONTRACT), + contractCreate(NEGATIVE_ASSOCIATIONS_CONTRACT), + cryptoCreate(TOKEN_TREASURY), + tokenCreate(TOKEN) + .tokenType(TokenType.FUNGIBLE_COMMON) + .initialSupply(50L) + .supplyKey(TOKEN_TREASURY) + .adminKey(TOKEN_TREASURY) + .treasury(TOKEN_TREASURY) + .exposingAddressTo(tokenAddress1::set), + tokenCreate(TOKEN1) + .tokenType(TokenType.FUNGIBLE_COMMON) + .initialSupply(50L) + .supplyKey(TOKEN_TREASURY) + .adminKey(TOKEN_TREASURY) + .treasury(TOKEN_TREASURY) + .exposingAddressTo(tokenAddress2::set), + cryptoCreate(ACCOUNT).exposingCreatedIdTo(id -> accountAddress.set(idAsHeadlongAddress(id))), + withOpContext((spec, custom) -> allRunFor( spec, contractCall( NEGATIVE_ASSOCIATIONS_CONTRACT, @@ -383,28 +383,24 @@ final Stream associateTokensNegativeScenarios() { .via(someNonExistingTokenArray) .logged(), getAccountInfo(ACCOUNT).hasToken(relationshipWith(TOKEN)), - getAccountInfo(ACCOUNT).hasToken(relationshipWith(TOKEN1))))) - .then( - childRecordsCheck( - nonExistingAccount, - CONTRACT_REVERT_EXECUTED, - recordWith().status(INVALID_ACCOUNT_ID)), - childRecordsCheck( - nonExistingTokenArray, SUCCESS, recordWith().status(SUCCESS)), - childRecordsCheck( - someNonExistingTokenArray, SUCCESS, recordWith().status(SUCCESS)), - childRecordsCheck( - zeroAccountAddress, - CONTRACT_REVERT_EXECUTED, - recordWith().status(INVALID_ACCOUNT_ID)), - childRecordsCheck( - nullTokenArray, - CONTRACT_REVERT_EXECUTED, - recordWith().status(INVALID_TOKEN_ID)), - childRecordsCheck( - nonExistingTokensInArray, - CONTRACT_REVERT_EXECUTED, - recordWith().status(INVALID_TOKEN_ID))); + getAccountInfo(ACCOUNT).hasToken(relationshipWith(TOKEN1)))), + childRecordsCheck( + nonExistingAccount, + CONTRACT_REVERT_EXECUTED, + recordWith().status(INVALID_ACCOUNT_ID)), + childRecordsCheck(nonExistingTokenArray, SUCCESS, recordWith().status(SUCCESS)), + childRecordsCheck( + someNonExistingTokenArray, SUCCESS, recordWith().status(SUCCESS)), + childRecordsCheck( + zeroAccountAddress, + CONTRACT_REVERT_EXECUTED, + recordWith().status(INVALID_ACCOUNT_ID)), + childRecordsCheck( + nullTokenArray, CONTRACT_REVERT_EXECUTED, recordWith().status(INVALID_TOKEN_ID)), + childRecordsCheck( + nonExistingTokensInArray, + CONTRACT_REVERT_EXECUTED, + recordWith().status(INVALID_TOKEN_ID))); } @HapiTest @@ -415,20 +411,19 @@ final Stream associateTokenNegativeScenarios() { final var nullAccount = "nullAccount"; final var nonExistingToken = "nonExistingToken"; final var nullToken = "nullToken"; - return defaultHapiSpec("associateTokenNegativeScenarios") - .given( - uploadInitCode(NEGATIVE_ASSOCIATIONS_CONTRACT), - contractCreate(NEGATIVE_ASSOCIATIONS_CONTRACT), - cryptoCreate(TOKEN_TREASURY), - tokenCreate(TOKEN) - .tokenType(TokenType.FUNGIBLE_COMMON) - .initialSupply(50L) - .supplyKey(TOKEN_TREASURY) - .adminKey(TOKEN_TREASURY) - .treasury(TOKEN_TREASURY) - .exposingAddressTo(tokenAddress::set), - cryptoCreate(ACCOUNT).exposingCreatedIdTo(id -> accountAddress.set(idAsHeadlongAddress(id)))) - .when(withOpContext((spec, custom) -> allRunFor( + return hapiTest( + uploadInitCode(NEGATIVE_ASSOCIATIONS_CONTRACT), + contractCreate(NEGATIVE_ASSOCIATIONS_CONTRACT), + cryptoCreate(TOKEN_TREASURY), + tokenCreate(TOKEN) + .tokenType(TokenType.FUNGIBLE_COMMON) + .initialSupply(50L) + .supplyKey(TOKEN_TREASURY) + .adminKey(TOKEN_TREASURY) + .treasury(TOKEN_TREASURY) + .exposingAddressTo(tokenAddress::set), + cryptoCreate(ACCOUNT).exposingCreatedIdTo(id -> accountAddress.set(idAsHeadlongAddress(id))), + withOpContext((spec, custom) -> allRunFor( spec, newKeyNamed(CONTRACT_KEY).shape(KEY_SHAPE.signedWith(sigs(ON, NEGATIVE_ASSOCIATIONS_CONTRACT))), cryptoUpdate(ACCOUNT).key(CONTRACT_KEY), @@ -467,23 +462,16 @@ final Stream associateTokenNegativeScenarios() { .gas(GAS_TO_OFFER) .via(nullToken) .logged(), - getAccountInfo(ACCOUNT).hasNoTokenRelationship(TOKEN)))) - .then( - childRecordsCheck( - nonExistingAccount, - CONTRACT_REVERT_EXECUTED, - recordWith().status(INVALID_ACCOUNT_ID)), - childRecordsCheck( - nullAccount, - CONTRACT_REVERT_EXECUTED, - recordWith().status(INVALID_ACCOUNT_ID)), - childRecordsCheck( - nonExistingToken, - CONTRACT_REVERT_EXECUTED, - recordWith().status(INVALID_TOKEN_ID)), - childRecordsCheck( - nullToken, - CONTRACT_REVERT_EXECUTED, - recordWith().status(INVALID_TOKEN_ID))); + getAccountInfo(ACCOUNT).hasNoTokenRelationship(TOKEN))), + childRecordsCheck( + nonExistingAccount, + CONTRACT_REVERT_EXECUTED, + recordWith().status(INVALID_ACCOUNT_ID)), + childRecordsCheck( + nullAccount, CONTRACT_REVERT_EXECUTED, recordWith().status(INVALID_ACCOUNT_ID)), + childRecordsCheck( + nonExistingToken, CONTRACT_REVERT_EXECUTED, recordWith().status(INVALID_TOKEN_ID)), + childRecordsCheck( + nullToken, CONTRACT_REVERT_EXECUTED, recordWith().status(INVALID_TOKEN_ID))); } } diff --git a/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/precompile/AssociatePrecompileV2SecurityModelSuite.java b/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/precompile/AssociatePrecompileV2SecurityModelSuite.java index c1544502f315..7e4353002e9a 100644 --- a/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/precompile/AssociatePrecompileV2SecurityModelSuite.java +++ b/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/precompile/AssociatePrecompileV2SecurityModelSuite.java @@ -17,7 +17,7 @@ package com.hedera.services.bdd.suites.contract.precompile; import static com.hedera.services.bdd.junit.TestTags.SMART_CONTRACT; -import static com.hedera.services.bdd.spec.HapiSpec.defaultHapiSpec; +import static com.hedera.services.bdd.spec.HapiSpec.hapiTest; import static com.hedera.services.bdd.spec.assertions.ContractFnResultAsserts.resultWith; import static com.hedera.services.bdd.spec.assertions.TransactionRecordAsserts.recordWith; import static com.hedera.services.bdd.spec.keys.KeyShape.CONTRACT; @@ -96,49 +96,48 @@ public class AssociatePrecompileV2SecurityModelSuite { @HapiTest final Stream v2Security031AssociateSingleTokenWithDelegateContractKey() { - return defaultHapiSpec("v2Security031AssociateSingleTokenWithDelegateContractKey") - .given( - newKeyNamed(FREEZE_KEY), - newKeyNamed(KYC_KEY), - cryptoCreate(TOKEN_TREASURY).balance(ONE_HUNDRED_HBARS), - cryptoCreate(SIGNER).balance(ONE_MILLION_HBARS), - cryptoCreate(ACCOUNT).balance(10 * ONE_HUNDRED_HBARS), - tokenCreate(FUNGIBLE_TOKEN) - .tokenType(TokenType.FUNGIBLE_COMMON) - .treasury(TOKEN_TREASURY) - .supplyKey(TOKEN_TREASURY) - .adminKey(TOKEN_TREASURY), - tokenCreate(NON_FUNGIBLE_TOKEN) - .tokenType(TokenType.NON_FUNGIBLE_UNIQUE) - .initialSupply(0) - .treasury(TOKEN_TREASURY) - .adminKey(TOKEN_TREASURY) - .supplyKey(TOKEN_TREASURY), - tokenCreate(FROZEN_TOKEN) - .tokenType(FUNGIBLE_COMMON) - .treasury(TOKEN_TREASURY) - .initialSupply(TOTAL_SUPPLY) - .freezeKey(FREEZE_KEY) - .freezeDefault(true) - .adminKey(TOKEN_TREASURY) - .supplyKey(TOKEN_TREASURY), - tokenCreate(UNFROZEN_TOKEN) - .tokenType(FUNGIBLE_COMMON) - .treasury(TOKEN_TREASURY) - .freezeKey(FREEZE_KEY) - .freezeDefault(false) - .adminKey(TOKEN_TREASURY) - .supplyKey(TOKEN_TREASURY), - tokenCreate(KYC_TOKEN) - .tokenType(FUNGIBLE_COMMON) - .treasury(TOKEN_TREASURY) - .kycKey(KYC_KEY) - .adminKey(TOKEN_TREASURY) - .supplyKey(TOKEN_TREASURY), - uploadInitCode(ASSOCIATE_CONTRACT, MINT_TOKEN_CONTRACT), - contractCreate(MINT_TOKEN_CONTRACT), - contractCreate(ASSOCIATE_CONTRACT)) - .when(withOpContext((spec, opLog) -> allRunFor( + return hapiTest( + newKeyNamed(FREEZE_KEY), + newKeyNamed(KYC_KEY), + cryptoCreate(TOKEN_TREASURY).balance(ONE_HUNDRED_HBARS), + cryptoCreate(SIGNER).balance(ONE_MILLION_HBARS), + cryptoCreate(ACCOUNT).balance(10 * ONE_HUNDRED_HBARS), + tokenCreate(FUNGIBLE_TOKEN) + .tokenType(TokenType.FUNGIBLE_COMMON) + .treasury(TOKEN_TREASURY) + .supplyKey(TOKEN_TREASURY) + .adminKey(TOKEN_TREASURY), + tokenCreate(NON_FUNGIBLE_TOKEN) + .tokenType(TokenType.NON_FUNGIBLE_UNIQUE) + .initialSupply(0) + .treasury(TOKEN_TREASURY) + .adminKey(TOKEN_TREASURY) + .supplyKey(TOKEN_TREASURY), + tokenCreate(FROZEN_TOKEN) + .tokenType(FUNGIBLE_COMMON) + .treasury(TOKEN_TREASURY) + .initialSupply(TOTAL_SUPPLY) + .freezeKey(FREEZE_KEY) + .freezeDefault(true) + .adminKey(TOKEN_TREASURY) + .supplyKey(TOKEN_TREASURY), + tokenCreate(UNFROZEN_TOKEN) + .tokenType(FUNGIBLE_COMMON) + .treasury(TOKEN_TREASURY) + .freezeKey(FREEZE_KEY) + .freezeDefault(false) + .adminKey(TOKEN_TREASURY) + .supplyKey(TOKEN_TREASURY), + tokenCreate(KYC_TOKEN) + .tokenType(FUNGIBLE_COMMON) + .treasury(TOKEN_TREASURY) + .kycKey(KYC_KEY) + .adminKey(TOKEN_TREASURY) + .supplyKey(TOKEN_TREASURY), + uploadInitCode(ASSOCIATE_CONTRACT, MINT_TOKEN_CONTRACT), + contractCreate(MINT_TOKEN_CONTRACT), + contractCreate(ASSOCIATE_CONTRACT), + withOpContext((spec, opLog) -> allRunFor( spec, newKeyNamed(CONTRACT_KEY).shape(THRESHOLD_KEY_SHAPE.signedWith(sigs(ON, ASSOCIATE_CONTRACT))), cryptoUpdate(SIGNER).key(CONTRACT_KEY), @@ -202,8 +201,8 @@ final Stream v2Security031AssociateSingleTokenWithDelegateContractK .hasRetryPrecheckFrom(BUSY) .via("multipleTokensAssociate") .gas(GAS_TO_OFFER) - .hasKnownStatus(SUCCESS)))) - .then(getAccountInfo(ACCOUNT) + .hasKnownStatus(SUCCESS))), + getAccountInfo(ACCOUNT) .hasToken(relationshipWith(FUNGIBLE_TOKEN) .kyc(KycNotApplicable) .freeze(FreezeNotApplicable)) @@ -221,50 +220,49 @@ final Stream v2Security031AssociateSingleTokenWithDelegateContractK @HapiTest final Stream v2Security006TokenAssociateNegativeTests() { - return defaultHapiSpec("v2Security006TokenAssociateNegativeTests") - .given( - newKeyNamed(FREEZE_KEY), - newKeyNamed(KYC_KEY), - newKeyNamed(ADMIN_KEY), - cryptoCreate(TOKEN_TREASURY).balance(ONE_HUNDRED_HBARS), - cryptoCreate(SIGNER).balance(ONE_HUNDRED_HBARS), - cryptoCreate(ACCOUNT).balance(10 * ONE_HUNDRED_HBARS), - tokenCreate(FUNGIBLE_TOKEN) - .tokenType(TokenType.FUNGIBLE_COMMON) - .treasury(TOKEN_TREASURY) - .supplyKey(TOKEN_TREASURY) - .adminKey(TOKEN_TREASURY), - tokenCreate(NON_FUNGIBLE_TOKEN) - .tokenType(TokenType.NON_FUNGIBLE_UNIQUE) - .initialSupply(0) - .treasury(TOKEN_TREASURY) - .adminKey(ADMIN_KEY) - .supplyKey(TOKEN_TREASURY), - tokenCreate(FROZEN_TOKEN) - .tokenType(FUNGIBLE_COMMON) - .treasury(TOKEN_TREASURY) - .initialSupply(TOTAL_SUPPLY) - .freezeKey(FREEZE_KEY) - .freezeDefault(true) - .adminKey(TOKEN_TREASURY) - .supplyKey(TOKEN_TREASURY), - tokenCreate(UNFROZEN_TOKEN) - .tokenType(FUNGIBLE_COMMON) - .treasury(TOKEN_TREASURY) - .freezeKey(FREEZE_KEY) - .freezeDefault(false) - .adminKey(TOKEN_TREASURY) - .supplyKey(TOKEN_TREASURY), - tokenCreate(KYC_TOKEN) - .tokenType(FUNGIBLE_COMMON) - .treasury(TOKEN_TREASURY) - .kycKey(KYC_KEY) - .adminKey(TOKEN_TREASURY) - .supplyKey(TOKEN_TREASURY), - uploadInitCode(ASSOCIATE_CONTRACT, NESTED_ASSOCIATE_CONTRACT, MINT_TOKEN_CONTRACT), - contractCreate(ASSOCIATE_CONTRACT), - contractCreate(MINT_TOKEN_CONTRACT)) - .when(withOpContext((spec, opLog) -> allRunFor( + return hapiTest( + newKeyNamed(FREEZE_KEY), + newKeyNamed(KYC_KEY), + newKeyNamed(ADMIN_KEY), + cryptoCreate(TOKEN_TREASURY).balance(ONE_HUNDRED_HBARS), + cryptoCreate(SIGNER).balance(ONE_HUNDRED_HBARS), + cryptoCreate(ACCOUNT).balance(10 * ONE_HUNDRED_HBARS), + tokenCreate(FUNGIBLE_TOKEN) + .tokenType(TokenType.FUNGIBLE_COMMON) + .treasury(TOKEN_TREASURY) + .supplyKey(TOKEN_TREASURY) + .adminKey(TOKEN_TREASURY), + tokenCreate(NON_FUNGIBLE_TOKEN) + .tokenType(TokenType.NON_FUNGIBLE_UNIQUE) + .initialSupply(0) + .treasury(TOKEN_TREASURY) + .adminKey(ADMIN_KEY) + .supplyKey(TOKEN_TREASURY), + tokenCreate(FROZEN_TOKEN) + .tokenType(FUNGIBLE_COMMON) + .treasury(TOKEN_TREASURY) + .initialSupply(TOTAL_SUPPLY) + .freezeKey(FREEZE_KEY) + .freezeDefault(true) + .adminKey(TOKEN_TREASURY) + .supplyKey(TOKEN_TREASURY), + tokenCreate(UNFROZEN_TOKEN) + .tokenType(FUNGIBLE_COMMON) + .treasury(TOKEN_TREASURY) + .freezeKey(FREEZE_KEY) + .freezeDefault(false) + .adminKey(TOKEN_TREASURY) + .supplyKey(TOKEN_TREASURY), + tokenCreate(KYC_TOKEN) + .tokenType(FUNGIBLE_COMMON) + .treasury(TOKEN_TREASURY) + .kycKey(KYC_KEY) + .adminKey(TOKEN_TREASURY) + .supplyKey(TOKEN_TREASURY), + uploadInitCode(ASSOCIATE_CONTRACT, NESTED_ASSOCIATE_CONTRACT, MINT_TOKEN_CONTRACT), + contractCreate(ASSOCIATE_CONTRACT), + contractCreate(MINT_TOKEN_CONTRACT), + withOpContext((spec, opLog) -> allRunFor( spec, contractCreate( NESTED_ASSOCIATE_CONTRACT, @@ -372,71 +370,69 @@ final Stream v2Security006TokenAssociateNegativeTests() { .hasKnownStatus(CONTRACT_REVERT_EXECUTED), getTxnRecord("associateTokenToContractFails") .andAllChildRecords() - .logged()))) - .then( - childRecordsCheck( - "fungibleTokenAssociate", - CONTRACT_REVERT_EXECUTED, - recordWith() - .status(INVALID_FULL_PREFIX_SIGNATURE_FOR_PRECOMPILE) - .contractCallResult(resultWith() - .contractCallResult(htsPrecompileResult() - .withStatus(INVALID_FULL_PREFIX_SIGNATURE_FOR_PRECOMPILE)))), - childRecordsCheck( - "nonFungibleTokenAssociate", - CONTRACT_REVERT_EXECUTED, - recordWith() - .status(INVALID_FULL_PREFIX_SIGNATURE_FOR_PRECOMPILE) - .contractCallResult(resultWith() - .contractCallResult(htsPrecompileResult() - .withStatus(INVALID_FULL_PREFIX_SIGNATURE_FOR_PRECOMPILE)))), - childRecordsCheck( - "multipleTokensAssociate", - CONTRACT_REVERT_EXECUTED, - recordWith() - .status(INVALID_FULL_PREFIX_SIGNATURE_FOR_PRECOMPILE) - .contractCallResult(resultWith() - .contractCallResult(htsPrecompileResult() - .withStatus(INVALID_FULL_PREFIX_SIGNATURE_FOR_PRECOMPILE)))), - childRecordsCheck( - "nestedAssociateFungibleTxn", - CONTRACT_REVERT_EXECUTED, - recordWith() - .status(INVALID_FULL_PREFIX_SIGNATURE_FOR_PRECOMPILE) - .contractCallResult(resultWith() - .contractCallResult(htsPrecompileResult() - .withStatus(INVALID_FULL_PREFIX_SIGNATURE_FOR_PRECOMPILE)))), - childRecordsCheck( - "associateTokenToContractFails", - CONTRACT_REVERT_EXECUTED, - recordWith() - .status(INVALID_FULL_PREFIX_SIGNATURE_FOR_PRECOMPILE) - .contractCallResult(resultWith() - .contractCallResult(htsPrecompileResult() - .withStatus(INVALID_FULL_PREFIX_SIGNATURE_FOR_PRECOMPILE))))); + .logged())), + childRecordsCheck( + "fungibleTokenAssociate", + CONTRACT_REVERT_EXECUTED, + recordWith() + .status(INVALID_FULL_PREFIX_SIGNATURE_FOR_PRECOMPILE) + .contractCallResult(resultWith() + .contractCallResult(htsPrecompileResult() + .withStatus(INVALID_FULL_PREFIX_SIGNATURE_FOR_PRECOMPILE)))), + childRecordsCheck( + "nonFungibleTokenAssociate", + CONTRACT_REVERT_EXECUTED, + recordWith() + .status(INVALID_FULL_PREFIX_SIGNATURE_FOR_PRECOMPILE) + .contractCallResult(resultWith() + .contractCallResult(htsPrecompileResult() + .withStatus(INVALID_FULL_PREFIX_SIGNATURE_FOR_PRECOMPILE)))), + childRecordsCheck( + "multipleTokensAssociate", + CONTRACT_REVERT_EXECUTED, + recordWith() + .status(INVALID_FULL_PREFIX_SIGNATURE_FOR_PRECOMPILE) + .contractCallResult(resultWith() + .contractCallResult(htsPrecompileResult() + .withStatus(INVALID_FULL_PREFIX_SIGNATURE_FOR_PRECOMPILE)))), + childRecordsCheck( + "nestedAssociateFungibleTxn", + CONTRACT_REVERT_EXECUTED, + recordWith() + .status(INVALID_FULL_PREFIX_SIGNATURE_FOR_PRECOMPILE) + .contractCallResult(resultWith() + .contractCallResult(htsPrecompileResult() + .withStatus(INVALID_FULL_PREFIX_SIGNATURE_FOR_PRECOMPILE)))), + childRecordsCheck( + "associateTokenToContractFails", + CONTRACT_REVERT_EXECUTED, + recordWith() + .status(INVALID_FULL_PREFIX_SIGNATURE_FOR_PRECOMPILE) + .contractCallResult(resultWith() + .contractCallResult(htsPrecompileResult() + .withStatus(INVALID_FULL_PREFIX_SIGNATURE_FOR_PRECOMPILE))))); } @HapiTest final Stream v2Security010NestedAssociateNftAndNonFungibleTokens() { - return defaultHapiSpec("v2Security010NestedAssociateNftAndNonFungibleTokens") - .given( - cryptoCreate(ACCOUNT).balance(ONE_HUNDRED_HBARS), - cryptoCreate(TOKEN_TREASURY), - tokenCreate(FUNGIBLE_TOKEN) - .tokenType(FUNGIBLE_COMMON) - .supplyKey(TOKEN_TREASURY) - .adminKey(TOKEN_TREASURY) - .treasury(TOKEN_TREASURY), - tokenCreate(NON_FUNGIBLE_TOKEN) - .tokenType(NON_FUNGIBLE_UNIQUE) - .supplyKey(TOKEN_TREASURY) - .initialSupply(0) - .adminKey(TOKEN_TREASURY) - .treasury(TOKEN_TREASURY), - uploadInitCode(ASSOCIATE_CONTRACT, NESTED_ASSOCIATE_CONTRACT), - contractCreate(ASSOCIATE_CONTRACT)) - .when(withOpContext((spec, opLog) -> allRunFor( + return hapiTest( + cryptoCreate(ACCOUNT).balance(ONE_HUNDRED_HBARS), + cryptoCreate(TOKEN_TREASURY), + tokenCreate(FUNGIBLE_TOKEN) + .tokenType(FUNGIBLE_COMMON) + .supplyKey(TOKEN_TREASURY) + .adminKey(TOKEN_TREASURY) + .treasury(TOKEN_TREASURY), + tokenCreate(NON_FUNGIBLE_TOKEN) + .tokenType(NON_FUNGIBLE_UNIQUE) + .supplyKey(TOKEN_TREASURY) + .initialSupply(0) + .adminKey(TOKEN_TREASURY) + .treasury(TOKEN_TREASURY), + uploadInitCode(ASSOCIATE_CONTRACT, NESTED_ASSOCIATE_CONTRACT), + contractCreate(ASSOCIATE_CONTRACT), + withOpContext((spec, opLog) -> allRunFor( spec, contractCreate( NESTED_ASSOCIATE_CONTRACT, @@ -477,54 +473,52 @@ final Stream v2Security010NestedAssociateNftAndNonFungibleTokens() .hasRetryPrecheckFrom(BUSY) .via("nestedAssociateNonFungibleTxn") .gas(GAS_TO_OFFER) - .hasKnownStatus(SUCCESS)))) - .then( - getAccountInfo(ACCOUNT) - .hasToken(relationshipWith(FUNGIBLE_TOKEN) - .kyc(KycNotApplicable) - .freeze(FreezeNotApplicable)) - .hasToken(relationshipWith(NON_FUNGIBLE_TOKEN) - .kyc(KycNotApplicable) - .freeze(FreezeNotApplicable)), - childRecordsCheck( - "nestedAssociateFungibleTxn", - SUCCESS, - recordWith() - .status(SUCCESS) - .contractCallResult(resultWith() - .contractCallResult( - htsPrecompileResult().withStatus(SUCCESS)))), - childRecordsCheck( - "nestedAssociateNonFungibleTxn", - SUCCESS, - recordWith() - .status(SUCCESS) - .contractCallResult(resultWith() - .contractCallResult( - htsPrecompileResult().withStatus(SUCCESS))))); + .hasKnownStatus(SUCCESS))), + getAccountInfo(ACCOUNT) + .hasToken(relationshipWith(FUNGIBLE_TOKEN) + .kyc(KycNotApplicable) + .freeze(FreezeNotApplicable)) + .hasToken(relationshipWith(NON_FUNGIBLE_TOKEN) + .kyc(KycNotApplicable) + .freeze(FreezeNotApplicable)), + childRecordsCheck( + "nestedAssociateFungibleTxn", + SUCCESS, + recordWith() + .status(SUCCESS) + .contractCallResult(resultWith() + .contractCallResult( + htsPrecompileResult().withStatus(SUCCESS)))), + childRecordsCheck( + "nestedAssociateNonFungibleTxn", + SUCCESS, + recordWith() + .status(SUCCESS) + .contractCallResult(resultWith() + .contractCallResult( + htsPrecompileResult().withStatus(SUCCESS))))); } @HapiTest final Stream V2Security036TokenAssociateFromDelegateCallWithDelegateContractId() { - return defaultHapiSpec("v2Security010NestedAssociateNftAndNonFungibleTokens") - .given( - cryptoCreate(ACCOUNT).balance(ONE_HUNDRED_HBARS), - cryptoCreate(TOKEN_TREASURY), - tokenCreate(FUNGIBLE_TOKEN) - .tokenType(FUNGIBLE_COMMON) - .supplyKey(TOKEN_TREASURY) - .adminKey(TOKEN_TREASURY) - .treasury(TOKEN_TREASURY), - tokenCreate(NON_FUNGIBLE_TOKEN) - .tokenType(NON_FUNGIBLE_UNIQUE) - .supplyKey(TOKEN_TREASURY) - .initialSupply(0) - .adminKey(TOKEN_TREASURY) - .treasury(TOKEN_TREASURY), - uploadInitCode(ASSOCIATE_CONTRACT, NESTED_ASSOCIATE_CONTRACT), - contractCreate(ASSOCIATE_CONTRACT)) - .when(withOpContext((spec, opLog) -> allRunFor( + return hapiTest( + cryptoCreate(ACCOUNT).balance(ONE_HUNDRED_HBARS), + cryptoCreate(TOKEN_TREASURY), + tokenCreate(FUNGIBLE_TOKEN) + .tokenType(FUNGIBLE_COMMON) + .supplyKey(TOKEN_TREASURY) + .adminKey(TOKEN_TREASURY) + .treasury(TOKEN_TREASURY), + tokenCreate(NON_FUNGIBLE_TOKEN) + .tokenType(NON_FUNGIBLE_UNIQUE) + .supplyKey(TOKEN_TREASURY) + .initialSupply(0) + .adminKey(TOKEN_TREASURY) + .treasury(TOKEN_TREASURY), + uploadInitCode(ASSOCIATE_CONTRACT, NESTED_ASSOCIATE_CONTRACT), + contractCreate(ASSOCIATE_CONTRACT), + withOpContext((spec, opLog) -> allRunFor( spec, contractCreate( NESTED_ASSOCIATE_CONTRACT, @@ -565,55 +559,53 @@ final Stream V2Security036TokenAssociateFromDelegateCallWithDelegat .hasKnownStatus(SUCCESS), getTxnRecord("nestedAssociateNonFungibleTxn") .andAllChildRecords() - .logged()))) - .then( - getAccountInfo(ACCOUNT) - .hasToken(relationshipWith(FUNGIBLE_TOKEN) - .kyc(KycNotApplicable) - .freeze(FreezeNotApplicable)) - .hasToken(relationshipWith(NON_FUNGIBLE_TOKEN) - .kyc(KycNotApplicable) - .freeze(FreezeNotApplicable)), - childRecordsCheck( - "nestedAssociateFungibleTxn", - SUCCESS, - recordWith() - .status(SUCCESS) - .contractCallResult(resultWith() - .contractCallResult( - htsPrecompileResult().withStatus(SUCCESS)))), - childRecordsCheck( - "nestedAssociateNonFungibleTxn", - SUCCESS, - recordWith() - .status(SUCCESS) - .contractCallResult(resultWith() - .contractCallResult( - htsPrecompileResult().withStatus(SUCCESS))))); + .logged())), + getAccountInfo(ACCOUNT) + .hasToken(relationshipWith(FUNGIBLE_TOKEN) + .kyc(KycNotApplicable) + .freeze(FreezeNotApplicable)) + .hasToken(relationshipWith(NON_FUNGIBLE_TOKEN) + .kyc(KycNotApplicable) + .freeze(FreezeNotApplicable)), + childRecordsCheck( + "nestedAssociateFungibleTxn", + SUCCESS, + recordWith() + .status(SUCCESS) + .contractCallResult(resultWith() + .contractCallResult( + htsPrecompileResult().withStatus(SUCCESS)))), + childRecordsCheck( + "nestedAssociateNonFungibleTxn", + SUCCESS, + recordWith() + .status(SUCCESS) + .contractCallResult(resultWith() + .contractCallResult( + htsPrecompileResult().withStatus(SUCCESS))))); } @HapiTest final Stream V2Security041TokenAssociateFromStaticcallAndCallcode() { - return defaultHapiSpec("V2Security041TokenAssociateFromStaticcallAndCallcode") - .given( - cryptoCreate(ACCOUNT).balance(ONE_HUNDRED_HBARS), - cryptoCreate(TOKEN_TREASURY).balance(THOUSAND_HBAR), - tokenCreate(FUNGIBLE_TOKEN) - .tokenType(FUNGIBLE_COMMON) - .supplyKey(TOKEN_TREASURY) - .adminKey(TOKEN_TREASURY) - .treasury(TOKEN_TREASURY), - tokenCreate(NON_FUNGIBLE_TOKEN) - .tokenType(NON_FUNGIBLE_UNIQUE) - .supplyKey(TOKEN_TREASURY) - .initialSupply(0) - .adminKey(TOKEN_TREASURY) - .treasury(TOKEN_TREASURY), - uploadInitCode(ASSOCIATE_CONTRACT, NESTED_ASSOCIATE_CONTRACT, CALLCODE_CONTRACT), - contractCreate(ASSOCIATE_CONTRACT), - contractCreate(CALLCODE_CONTRACT)) - .when(withOpContext((spec, opLog) -> allRunFor( + return hapiTest( + cryptoCreate(ACCOUNT).balance(ONE_HUNDRED_HBARS), + cryptoCreate(TOKEN_TREASURY).balance(THOUSAND_HBAR), + tokenCreate(FUNGIBLE_TOKEN) + .tokenType(FUNGIBLE_COMMON) + .supplyKey(TOKEN_TREASURY) + .adminKey(TOKEN_TREASURY) + .treasury(TOKEN_TREASURY), + tokenCreate(NON_FUNGIBLE_TOKEN) + .tokenType(NON_FUNGIBLE_UNIQUE) + .supplyKey(TOKEN_TREASURY) + .initialSupply(0) + .adminKey(TOKEN_TREASURY) + .treasury(TOKEN_TREASURY), + uploadInitCode(ASSOCIATE_CONTRACT, NESTED_ASSOCIATE_CONTRACT, CALLCODE_CONTRACT), + contractCreate(ASSOCIATE_CONTRACT), + contractCreate(CALLCODE_CONTRACT), + withOpContext((spec, opLog) -> allRunFor( spec, contractCreate( NESTED_ASSOCIATE_CONTRACT, @@ -651,12 +643,14 @@ final Stream V2Security041TokenAssociateFromStaticcallAndCallcode() asHeadlongAddress(getNestedContractAddress(ASSOCIATE_CONTRACT, spec)), Bytes.wrap(AssociationsTranslator.ASSOCIATE_ONE .encodeCallWithArgs( - HapiParserUtil.asHeadlongAddress(asAddress( - spec.registry() - .getAccountID(ACCOUNT))), - HapiParserUtil.asHeadlongAddress(asAddress( - spec.registry() - .getTokenID(FUNGIBLE_TOKEN)))) + HapiParserUtil.asHeadlongAddress( + asAddress( + spec.registry() + .getAccountID(ACCOUNT))), + HapiParserUtil.asHeadlongAddress( + asAddress( + spec.registry() + .getTokenID(FUNGIBLE_TOKEN)))) .array()) .toArray()) .via("associateCallcodeFungibleTxn") @@ -669,10 +663,9 @@ final Stream V2Security041TokenAssociateFromStaticcallAndCallcode() .hasKnownStatus(CONTRACT_REVERT_EXECUTED), getTxnRecord("associateCallcodeFungibleTxn") .andAllChildRecords() - .logged()))) - .then( - emptyChildRecordsCheck("associateStaticcallFungibleTxn", CONTRACT_REVERT_EXECUTED), - emptyChildRecordsCheck("associateCallcodeFungibleTxn", CONTRACT_REVERT_EXECUTED), - getAccountInfo(ACCOUNT).hasNoTokenRelationship(FUNGIBLE_TOKEN)); + .logged())), + emptyChildRecordsCheck("associateStaticcallFungibleTxn", CONTRACT_REVERT_EXECUTED), + emptyChildRecordsCheck("associateCallcodeFungibleTxn", CONTRACT_REVERT_EXECUTED), + getAccountInfo(ACCOUNT).hasNoTokenRelationship(FUNGIBLE_TOKEN)); } } diff --git a/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/precompile/ContractBurnHTSSuite.java b/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/precompile/ContractBurnHTSSuite.java index 8336e366bd8a..192fa3cc58a0 100644 --- a/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/precompile/ContractBurnHTSSuite.java +++ b/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/precompile/ContractBurnHTSSuite.java @@ -18,7 +18,6 @@ import static com.google.protobuf.ByteString.copyFromUtf8; import static com.hedera.services.bdd.junit.TestTags.SMART_CONTRACT; -import static com.hedera.services.bdd.spec.HapiSpec.defaultHapiSpec; import static com.hedera.services.bdd.spec.HapiSpec.hapiTest; import static com.hedera.services.bdd.spec.assertions.TransactionRecordAsserts.recordWith; import static com.hedera.services.bdd.spec.queries.QueryVerbs.getAccountBalance; @@ -160,52 +159,44 @@ final Stream burnWithNegativeAmount() { final var negativeBurnNFT = "negativeBurnNFT"; final AtomicReference
tokenAddress = new AtomicReference<>(); final AtomicReference
nftAddress = new AtomicReference<>(); - return defaultHapiSpec("burnWithNegativeAmount") - .given( - uploadInitCode(NEGATIVE_BURN_CONTRACT), - contractCreate(NEGATIVE_BURN_CONTRACT), - cryptoCreate(TOKEN_TREASURY), - tokenCreate(TOKEN) - .tokenType(FUNGIBLE_COMMON) - .treasury(TOKEN_TREASURY) - .initialSupply(1_000L) - .exposingAddressTo(tokenAddress::set), - tokenCreate(NFT) - .tokenType(NON_FUNGIBLE_UNIQUE) - .treasury(TOKEN_TREASURY) - .initialSupply(0L) - .supplyKey(TOKEN_TREASURY) - .adminKey(TOKEN_TREASURY) - .exposingAddressTo(nftAddress::set), - mintToken(NFT, List.of(copyFromUtf8(FIRST), copyFromUtf8(SECOND)))) - .when( - sourcing(() -> contractCall( - NEGATIVE_BURN_CONTRACT, "burnFungibleNegativeLong", tokenAddress.get()) - .gas(GAS_TO_OFFER) - .hasKnownStatus(CONTRACT_REVERT_EXECUTED) - .via(negativeBurnFungible) - .logged()), - newKeyNamed(CONTRACT_KEY).shape(KeyShape.CONTRACT.signedWith(NEGATIVE_BURN_CONTRACT)), - tokenUpdate(NFT).supplyKey(CONTRACT_KEY).signedByPayerAnd(TOKEN_TREASURY), - sourcing(() -> contractCall( - NEGATIVE_BURN_CONTRACT, "burnNFTNegativeLong", nftAddress.get(), new long[] { - 1L, 2L - }) - .gas(GAS_TO_OFFER) - .hasKnownStatus(SUCCESS) - .payingWith(TOKEN_TREASURY) - .signingWith(TOKEN_TREASURY) - .via(negativeBurnNFT) - .logged())) - .then( - childRecordsCheck( - negativeBurnFungible, - CONTRACT_REVERT_EXECUTED, - recordWith().status(INVALID_TOKEN_BURN_AMOUNT)), - childRecordsCheck(negativeBurnNFT, SUCCESS, recordWith().status(SUCCESS)), - getAccountBalance(TOKEN_TREASURY) - .hasTokenBalance(TOKEN, 1_000) - .hasTokenBalance(NFT, 0)); + return hapiTest( + uploadInitCode(NEGATIVE_BURN_CONTRACT), + contractCreate(NEGATIVE_BURN_CONTRACT), + cryptoCreate(TOKEN_TREASURY), + tokenCreate(TOKEN) + .tokenType(FUNGIBLE_COMMON) + .treasury(TOKEN_TREASURY) + .initialSupply(1_000L) + .exposingAddressTo(tokenAddress::set), + tokenCreate(NFT) + .tokenType(NON_FUNGIBLE_UNIQUE) + .treasury(TOKEN_TREASURY) + .initialSupply(0L) + .supplyKey(TOKEN_TREASURY) + .adminKey(TOKEN_TREASURY) + .exposingAddressTo(nftAddress::set), + mintToken(NFT, List.of(copyFromUtf8(FIRST), copyFromUtf8(SECOND))), + sourcing(() -> contractCall(NEGATIVE_BURN_CONTRACT, "burnFungibleNegativeLong", tokenAddress.get()) + .gas(GAS_TO_OFFER) + .hasKnownStatus(CONTRACT_REVERT_EXECUTED) + .via(negativeBurnFungible) + .logged()), + newKeyNamed(CONTRACT_KEY).shape(KeyShape.CONTRACT.signedWith(NEGATIVE_BURN_CONTRACT)), + tokenUpdate(NFT).supplyKey(CONTRACT_KEY).signedByPayerAnd(TOKEN_TREASURY), + sourcing(() -> contractCall( + NEGATIVE_BURN_CONTRACT, "burnNFTNegativeLong", nftAddress.get(), new long[] {1L, 2L}) + .gas(GAS_TO_OFFER) + .hasKnownStatus(SUCCESS) + .payingWith(TOKEN_TREASURY) + .signingWith(TOKEN_TREASURY) + .via(negativeBurnNFT) + .logged()), + childRecordsCheck( + negativeBurnFungible, + CONTRACT_REVERT_EXECUTED, + recordWith().status(INVALID_TOKEN_BURN_AMOUNT)), + childRecordsCheck(negativeBurnNFT, SUCCESS, recordWith().status(SUCCESS)), + getAccountBalance(TOKEN_TREASURY).hasTokenBalance(TOKEN, 1_000).hasTokenBalance(NFT, 0)); } @HapiTest @@ -214,102 +205,89 @@ final Stream burnWithExtremeAmount() { final AtomicReference
nftAddress = new AtomicReference<>(); final var fungibleExtremeAmount = "fungibleExtremeAmounts"; final var nftExtremeAmount = "NFTExtremeAmounts"; - return defaultHapiSpec("burnAboveMaxLongAmount") - .given( - uploadInitCode(NEGATIVE_BURN_CONTRACT), - contractCreate(NEGATIVE_BURN_CONTRACT), - cryptoCreate(TOKEN_TREASURY), - tokenCreate(TOKEN) - .tokenType(FUNGIBLE_COMMON) - .treasury(TOKEN_TREASURY) - .initialSupply(1_000) - .exposingAddressTo(tokenAddress::set), - tokenCreate(NFT) - .tokenType(NON_FUNGIBLE_UNIQUE) - .treasury(TOKEN_TREASURY) - .initialSupply(0L) - .supplyKey(TOKEN_TREASURY) - .adminKey(TOKEN_TREASURY) - .exposingAddressTo(nftAddress::set), - mintToken(NFT, List.of(copyFromUtf8(FIRST), copyFromUtf8(SECOND)))) - .when( - sourcing(() -> contractCall( - NEGATIVE_BURN_CONTRACT, "burnFungibleWithExtremeAmounts", tokenAddress.get()) + return hapiTest( + uploadInitCode(NEGATIVE_BURN_CONTRACT), + contractCreate(NEGATIVE_BURN_CONTRACT), + cryptoCreate(TOKEN_TREASURY), + tokenCreate(TOKEN) + .tokenType(FUNGIBLE_COMMON) + .treasury(TOKEN_TREASURY) + .initialSupply(1_000) + .exposingAddressTo(tokenAddress::set), + tokenCreate(NFT) + .tokenType(NON_FUNGIBLE_UNIQUE) + .treasury(TOKEN_TREASURY) + .initialSupply(0L) + .supplyKey(TOKEN_TREASURY) + .adminKey(TOKEN_TREASURY) + .exposingAddressTo(nftAddress::set), + mintToken(NFT, List.of(copyFromUtf8(FIRST), copyFromUtf8(SECOND))), + sourcing( + () -> contractCall(NEGATIVE_BURN_CONTRACT, "burnFungibleWithExtremeAmounts", tokenAddress.get()) .gas(GAS_TO_OFFER) .hasKnownStatus(CONTRACT_REVERT_EXECUTED) .via(fungibleExtremeAmount) .logged()), - newKeyNamed(CONTRACT_KEY).shape(KeyShape.CONTRACT.signedWith(NEGATIVE_BURN_CONTRACT)), - tokenUpdate(NFT).supplyKey(CONTRACT_KEY).signedByPayerAnd(TOKEN_TREASURY), - sourcing(() -> contractCall( - NEGATIVE_BURN_CONTRACT, - "burnNFTWithExtremeAmounts", - nftAddress.get(), - new long[] {1L, 2L}) - .gas(GAS_TO_OFFER) - .hasKnownStatus(CONTRACT_REVERT_EXECUTED) - .payingWith(TOKEN_TREASURY) - .signingWith(TOKEN_TREASURY) - .via(nftExtremeAmount) - .logged())) - .then( - emptyChildRecordsCheck(fungibleExtremeAmount, CONTRACT_REVERT_EXECUTED), - emptyChildRecordsCheck(nftExtremeAmount, CONTRACT_REVERT_EXECUTED), - getAccountBalance(TOKEN_TREASURY).hasTokenBalance(TOKEN, 1_000), - getAccountBalance(TOKEN_TREASURY).hasTokenBalance(NFT, 2)); + newKeyNamed(CONTRACT_KEY).shape(KeyShape.CONTRACT.signedWith(NEGATIVE_BURN_CONTRACT)), + tokenUpdate(NFT).supplyKey(CONTRACT_KEY).signedByPayerAnd(TOKEN_TREASURY), + sourcing(() -> contractCall( + NEGATIVE_BURN_CONTRACT, "burnNFTWithExtremeAmounts", nftAddress.get(), new long[] { + 1L, 2L + }) + .gas(GAS_TO_OFFER) + .hasKnownStatus(CONTRACT_REVERT_EXECUTED) + .payingWith(TOKEN_TREASURY) + .signingWith(TOKEN_TREASURY) + .via(nftExtremeAmount) + .logged()), + emptyChildRecordsCheck(fungibleExtremeAmount, CONTRACT_REVERT_EXECUTED), + emptyChildRecordsCheck(nftExtremeAmount, CONTRACT_REVERT_EXECUTED), + getAccountBalance(TOKEN_TREASURY).hasTokenBalance(TOKEN, 1_000), + getAccountBalance(TOKEN_TREASURY).hasTokenBalance(NFT, 2)); } @HapiTest final Stream burnWithZeroAddress() { - return defaultHapiSpec("burnWithZeroAddress") - .given(uploadInitCode(NEGATIVE_BURN_CONTRACT), contractCreate(NEGATIVE_BURN_CONTRACT)) - .when( - sourcing(() -> contractCall(NEGATIVE_BURN_CONTRACT, "burnFungibleZeroAddress") - .gas(GAS_TO_OFFER) - .hasKnownStatus(CONTRACT_REVERT_EXECUTED) - .via("zeroAddress") - .logged()), - sourcing(() -> contractCall(NEGATIVE_BURN_CONTRACT, "burnNFTZeroAddress", new long[] {1L, 2L}) - .gas(GAS_TO_OFFER) - .hasKnownStatus(CONTRACT_REVERT_EXECUTED) - .via("zeroAddressNFT") - .logged())) - .then( - childRecordsCheck( - "zeroAddress", - CONTRACT_REVERT_EXECUTED, - recordWith().status(INVALID_TOKEN_ID)), - childRecordsCheck( - "zeroAddressNFT", - CONTRACT_REVERT_EXECUTED, - recordWith().status(INVALID_TOKEN_ID))); + return hapiTest( + uploadInitCode(NEGATIVE_BURN_CONTRACT), + contractCreate(NEGATIVE_BURN_CONTRACT), + sourcing(() -> contractCall(NEGATIVE_BURN_CONTRACT, "burnFungibleZeroAddress") + .gas(GAS_TO_OFFER) + .hasKnownStatus(CONTRACT_REVERT_EXECUTED) + .via("zeroAddress") + .logged()), + sourcing(() -> contractCall(NEGATIVE_BURN_CONTRACT, "burnNFTZeroAddress", new long[] {1L, 2L}) + .gas(GAS_TO_OFFER) + .hasKnownStatus(CONTRACT_REVERT_EXECUTED) + .via("zeroAddressNFT") + .logged()), + childRecordsCheck( + "zeroAddress", CONTRACT_REVERT_EXECUTED, recordWith().status(INVALID_TOKEN_ID)), + childRecordsCheck( + "zeroAddressNFT", CONTRACT_REVERT_EXECUTED, recordWith().status(INVALID_TOKEN_ID))); } @HapiTest final Stream burnWithInvalidAddress() { - return defaultHapiSpec("burnWithInvalidAddress") - .given(uploadInitCode(NEGATIVE_BURN_CONTRACT), contractCreate(NEGATIVE_BURN_CONTRACT)) - .when( - sourcing(() -> contractCall(NEGATIVE_BURN_CONTRACT, "burnFungibleInvalidAddress") - .gas(GAS_TO_OFFER) - .hasKnownStatus(CONTRACT_REVERT_EXECUTED) - .via("invalidAddress") - .logged()), - sourcing( - () -> contractCall(NEGATIVE_BURN_CONTRACT, "burnNFTInvalidAddress", new long[] {1L, 2L}) - .gas(GAS_TO_OFFER) - .hasKnownStatus(CONTRACT_REVERT_EXECUTED) - .via("invalidAddressNFT") - .logged())) - .then( - childRecordsCheck( - "invalidAddress", - CONTRACT_REVERT_EXECUTED, - recordWith().status(INVALID_TOKEN_ID)), - childRecordsCheck( - "invalidAddressNFT", - CONTRACT_REVERT_EXECUTED, - recordWith().status(INVALID_TOKEN_ID))); + return hapiTest( + uploadInitCode(NEGATIVE_BURN_CONTRACT), + contractCreate(NEGATIVE_BURN_CONTRACT), + sourcing(() -> contractCall(NEGATIVE_BURN_CONTRACT, "burnFungibleInvalidAddress") + .gas(GAS_TO_OFFER) + .hasKnownStatus(CONTRACT_REVERT_EXECUTED) + .via("invalidAddress") + .logged()), + sourcing(() -> contractCall(NEGATIVE_BURN_CONTRACT, "burnNFTInvalidAddress", new long[] {1L, 2L}) + .gas(GAS_TO_OFFER) + .hasKnownStatus(CONTRACT_REVERT_EXECUTED) + .via("invalidAddressNFT") + .logged()), + childRecordsCheck( + "invalidAddress", CONTRACT_REVERT_EXECUTED, recordWith().status(INVALID_TOKEN_ID)), + childRecordsCheck( + "invalidAddressNFT", + CONTRACT_REVERT_EXECUTED, + recordWith().status(INVALID_TOKEN_ID))); } @HapiTest @@ -318,43 +296,39 @@ final Stream burnWithInvalidSerials() { final AtomicReference
nftAddress = new AtomicReference<>(); final var negativeBurnFungible = "negativeBurnFungible"; final var negativeBurnNft = "negativeBurnNft"; - return defaultHapiSpec("burnWithInvalidSerials") - .given( - uploadInitCode(NEGATIVE_BURN_CONTRACT), - contractCreate(NEGATIVE_BURN_CONTRACT), - cryptoCreate(TOKEN_TREASURY), - tokenCreate(TOKEN) - .tokenType(FUNGIBLE_COMMON) - .treasury(TOKEN_TREASURY) - .initialSupply(1_000) - .exposingAddressTo(tokenAddress::set), - tokenCreate(NFT) - .tokenType(NON_FUNGIBLE_UNIQUE) - .treasury(TOKEN_TREASURY) - .initialSupply(0L) - .supplyKey(TOKEN_TREASURY) - .adminKey(TOKEN_TREASURY) - .exposingAddressTo(nftAddress::set), - mintToken(NFT, List.of(copyFromUtf8(FIRST), copyFromUtf8(SECOND)))) - .when( - sourcing(() -> contractCall( - NEGATIVE_BURN_CONTRACT, "burnFungibleWithInvalidSerials", tokenAddress.get()) + return hapiTest( + uploadInitCode(NEGATIVE_BURN_CONTRACT), + contractCreate(NEGATIVE_BURN_CONTRACT), + cryptoCreate(TOKEN_TREASURY), + tokenCreate(TOKEN) + .tokenType(FUNGIBLE_COMMON) + .treasury(TOKEN_TREASURY) + .initialSupply(1_000) + .exposingAddressTo(tokenAddress::set), + tokenCreate(NFT) + .tokenType(NON_FUNGIBLE_UNIQUE) + .treasury(TOKEN_TREASURY) + .initialSupply(0L) + .supplyKey(TOKEN_TREASURY) + .adminKey(TOKEN_TREASURY) + .exposingAddressTo(nftAddress::set), + mintToken(NFT, List.of(copyFromUtf8(FIRST), copyFromUtf8(SECOND))), + sourcing( + () -> contractCall(NEGATIVE_BURN_CONTRACT, "burnFungibleWithInvalidSerials", tokenAddress.get()) .gas(GAS_TO_OFFER) .hasKnownStatus(CONTRACT_REVERT_EXECUTED) .via(negativeBurnFungible) .logged()), - sourcing(() -> contractCall( - NEGATIVE_BURN_CONTRACT, "burnNFTWithInvalidSerials", nftAddress.get()) - .gas(GAS_TO_OFFER) - .hasKnownStatus(CONTRACT_REVERT_EXECUTED) - .payingWith(TOKEN_TREASURY) - .signingWith(TOKEN_TREASURY) - .via(negativeBurnNft) - .logged())) - .then( - emptyChildRecordsCheck(negativeBurnFungible, CONTRACT_REVERT_EXECUTED), - emptyChildRecordsCheck(negativeBurnNft, CONTRACT_REVERT_EXECUTED), - getAccountBalance(TOKEN_TREASURY).hasTokenBalance(TOKEN, 1_000), - getAccountBalance(TOKEN_TREASURY).hasTokenBalance(NFT, 2)); + sourcing(() -> contractCall(NEGATIVE_BURN_CONTRACT, "burnNFTWithInvalidSerials", nftAddress.get()) + .gas(GAS_TO_OFFER) + .hasKnownStatus(CONTRACT_REVERT_EXECUTED) + .payingWith(TOKEN_TREASURY) + .signingWith(TOKEN_TREASURY) + .via(negativeBurnNft) + .logged()), + emptyChildRecordsCheck(negativeBurnFungible, CONTRACT_REVERT_EXECUTED), + emptyChildRecordsCheck(negativeBurnNft, CONTRACT_REVERT_EXECUTED), + getAccountBalance(TOKEN_TREASURY).hasTokenBalance(TOKEN, 1_000), + getAccountBalance(TOKEN_TREASURY).hasTokenBalance(NFT, 2)); } } diff --git a/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/precompile/ContractBurnHTSV2SecurityModelSuite.java b/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/precompile/ContractBurnHTSV2SecurityModelSuite.java index 56568b8e8ef1..805e8eeb983a 100644 --- a/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/precompile/ContractBurnHTSV2SecurityModelSuite.java +++ b/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/precompile/ContractBurnHTSV2SecurityModelSuite.java @@ -19,7 +19,7 @@ import static com.google.protobuf.ByteString.copyFromUtf8; import static com.hedera.services.bdd.spec.HapiPropertySource.asDotDelimitedLongArray; import static com.hedera.services.bdd.spec.HapiPropertySource.asToken; -import static com.hedera.services.bdd.spec.HapiSpec.defaultHapiSpec; +import static com.hedera.services.bdd.spec.HapiSpec.hapiTest; import static com.hedera.services.bdd.spec.assertions.AssertUtils.inOrder; import static com.hedera.services.bdd.spec.assertions.ContractFnResultAsserts.resultWith; import static com.hedera.services.bdd.spec.assertions.ContractLogAsserts.logWith; @@ -113,22 +113,21 @@ final Stream V2Security004FungibleTokenBurnPositive() { final var amountToBurn = 5L; final AtomicReference fungible = new AtomicReference<>(); // sync - return defaultHapiSpec("V2Security004FungibleTokenBurnPositive") - .given( - // overriding(CONTRACTS_MAX_NUM_WITH_HAPI_SIGS_ACCESS, - // CONTRACTS_V2_SECURITY_MODEL_BLOCK_CUTOFF), - cryptoCreate(TOKEN_TREASURY), - cryptoCreate(SIGNER2), - cryptoCreate(SIGNER).balance(ONE_MILLION_HBARS), - tokenCreate(FUNGIBLE_TOKEN) - .tokenType(TokenType.FUNGIBLE_COMMON) - .initialSupply(initialAmount) - .treasury(TOKEN_TREASURY) - .adminKey(TOKEN_TREASURY) - .supplyKey(TOKEN_TREASURY) - .exposingCreatedIdTo(idLit -> fungible.set(asToken(idLit))), - uploadInitCode(MIXED_BURN_TOKEN)) - .when(withOpContext((spec, opLog) -> allRunFor( + return hapiTest( + // overriding(CONTRACTS_MAX_NUM_WITH_HAPI_SIGS_ACCESS, + // CONTRACTS_V2_SECURITY_MODEL_BLOCK_CUTOFF), + cryptoCreate(TOKEN_TREASURY), + cryptoCreate(SIGNER2), + cryptoCreate(SIGNER).balance(ONE_MILLION_HBARS), + tokenCreate(FUNGIBLE_TOKEN) + .tokenType(TokenType.FUNGIBLE_COMMON) + .initialSupply(initialAmount) + .treasury(TOKEN_TREASURY) + .adminKey(TOKEN_TREASURY) + .supplyKey(TOKEN_TREASURY) + .exposingCreatedIdTo(idLit -> fungible.set(asToken(idLit))), + uploadInitCode(MIXED_BURN_TOKEN), + withOpContext((spec, opLog) -> allRunFor( spec, contractCreate( MIXED_BURN_TOKEN, @@ -190,21 +189,20 @@ final Stream V2Security004FungibleTokenBurnPositive() { .signedBy(SIGNER), // Assert that the token is burned - total supply should be decreased with the amount that was // burned - getTokenInfo(FUNGIBLE_TOKEN).hasTotalSupply(initialAmount - 4 * amountToBurn)))) - .then( - // Verify that each test case has 1 successful child record - getTxnRecord(SIGNER_BURNS_WITH_CONTRACT_ID) - .andAllChildRecords() - .hasChildRecords(recordWith().status(SUCCESS)), - getTxnRecord(SIGNER_HAS_KEY_WITH_CORRECT_CONTRACT_ID) - .andAllChildRecords() - .hasChildRecords(recordWith().status(SUCCESS)), - getTxnRecord(SIGNER_AND_PAYER_ARE_DIFFERENT) - .andAllChildRecords() - .hasChildRecords(recordWith().status(SUCCESS)), - getTxnRecord(SIGNER_BURNS_WITH_TRESHOLD_KEY) - .andAllChildRecords() - .hasChildRecords(recordWith().status(SUCCESS))); + getTokenInfo(FUNGIBLE_TOKEN).hasTotalSupply(initialAmount - 4 * amountToBurn))), + // Verify that each test case has 1 successful child record + getTxnRecord(SIGNER_BURNS_WITH_CONTRACT_ID) + .andAllChildRecords() + .hasChildRecords(recordWith().status(SUCCESS)), + getTxnRecord(SIGNER_HAS_KEY_WITH_CORRECT_CONTRACT_ID) + .andAllChildRecords() + .hasChildRecords(recordWith().status(SUCCESS)), + getTxnRecord(SIGNER_AND_PAYER_ARE_DIFFERENT) + .andAllChildRecords() + .hasChildRecords(recordWith().status(SUCCESS)), + getTxnRecord(SIGNER_BURNS_WITH_TRESHOLD_KEY) + .andAllChildRecords() + .hasChildRecords(recordWith().status(SUCCESS))); } @HapiTest @@ -215,24 +213,23 @@ final Stream V2Security005NonFungibleTokenBurnPositive() { final var serialNumber2 = new long[] {2L}; final var serialNumber3 = new long[] {3L}; - return defaultHapiSpec("V2Security005NonFungibleTokenBurnPositive") - .given( - cryptoCreate(TOKEN_TREASURY), - cryptoCreate(SIGNER2), - cryptoCreate(SIGNER).balance(ONE_MILLION_HBARS), - tokenCreate(NON_FUNGIBLE_TOKEN) - .tokenType(TokenType.NON_FUNGIBLE_UNIQUE) - .initialSupply(0) - .treasury(TOKEN_TREASURY) - .adminKey(TOKEN_TREASURY) - .supplyKey(TOKEN_TREASURY) - .exposingCreatedIdTo(idLit -> nonFungible.set(asToken(idLit))), - mintToken(NON_FUNGIBLE_TOKEN, List.of(copyFromUtf8(FIRST))), - mintToken(NON_FUNGIBLE_TOKEN, List.of(copyFromUtf8(SECOND))), - mintToken(NON_FUNGIBLE_TOKEN, List.of(copyFromUtf8(THIRD))), - mintToken(NON_FUNGIBLE_TOKEN, List.of(copyFromUtf8(FOURTH))), - uploadInitCode(MIXED_BURN_TOKEN)) - .when(withOpContext((spec, opLog) -> allRunFor( + return hapiTest( + cryptoCreate(TOKEN_TREASURY), + cryptoCreate(SIGNER2), + cryptoCreate(SIGNER).balance(ONE_MILLION_HBARS), + tokenCreate(NON_FUNGIBLE_TOKEN) + .tokenType(TokenType.NON_FUNGIBLE_UNIQUE) + .initialSupply(0) + .treasury(TOKEN_TREASURY) + .adminKey(TOKEN_TREASURY) + .supplyKey(TOKEN_TREASURY) + .exposingCreatedIdTo(idLit -> nonFungible.set(asToken(idLit))), + mintToken(NON_FUNGIBLE_TOKEN, List.of(copyFromUtf8(FIRST))), + mintToken(NON_FUNGIBLE_TOKEN, List.of(copyFromUtf8(SECOND))), + mintToken(NON_FUNGIBLE_TOKEN, List.of(copyFromUtf8(THIRD))), + mintToken(NON_FUNGIBLE_TOKEN, List.of(copyFromUtf8(FOURTH))), + uploadInitCode(MIXED_BURN_TOKEN), + withOpContext((spec, opLog) -> allRunFor( spec, contractCreate( MIXED_BURN_TOKEN, @@ -272,18 +269,17 @@ final Stream V2Security005NonFungibleTokenBurnPositive() { .hasRetryPrecheckFrom(BUSY) .payingWith(SIGNER2) .signedBy(SIGNER2, TOKEN_TREASURY), - getTokenInfo(NON_FUNGIBLE_TOKEN).hasTotalSupply(2 - amountToBurn)))) - .then( - // Verify that each test case has 1 successful child record - getTxnRecord(SIGNER_BURNS_WITH_CONTRACT_ID) - .andAllChildRecords() - .hasChildRecords(recordWith().status(SUCCESS)), - getTxnRecord(SIGNER_HAS_KEY_WITH_CORRECT_CONTRACT_ID) - .andAllChildRecords() - .hasChildRecords(recordWith().status(SUCCESS)), - getTxnRecord(SIGNER_AND_PAYER_ARE_DIFFERENT) - .andAllChildRecords() - .hasChildRecords(recordWith().status(SUCCESS))); + getTokenInfo(NON_FUNGIBLE_TOKEN).hasTotalSupply(2 - amountToBurn))), + // Verify that each test case has 1 successful child record + getTxnRecord(SIGNER_BURNS_WITH_CONTRACT_ID) + .andAllChildRecords() + .hasChildRecords(recordWith().status(SUCCESS)), + getTxnRecord(SIGNER_HAS_KEY_WITH_CORRECT_CONTRACT_ID) + .andAllChildRecords() + .hasChildRecords(recordWith().status(SUCCESS)), + getTxnRecord(SIGNER_AND_PAYER_ARE_DIFFERENT) + .andAllChildRecords() + .hasChildRecords(recordWith().status(SUCCESS))); } @HapiTest @@ -292,22 +288,21 @@ final Stream V2Security004FungibleTokenBurnNegative() { final var amountToBurn = 5L; final AtomicReference fungible = new AtomicReference<>(); - return defaultHapiSpec("V2Security004FungibleTokenBurnNegative") - .given( - cryptoCreate(TOKEN_TREASURY), - cryptoCreate(SIGNER).balance(ONE_MILLION_HBARS), - tokenCreate(FUNGIBLE_TOKEN) - .tokenType(TokenType.FUNGIBLE_COMMON) - .initialSupply(initialAmount) - .treasury(TOKEN_TREASURY) - .adminKey(TOKEN_TREASURY) - .supplyKey(TOKEN_TREASURY) - .exposingCreatedIdTo(idLit -> fungible.set(asToken(idLit))), - uploadInitCode(MIXED_BURN_TOKEN), - uploadInitCode(MINT_CONTRACT), - sourcing(() -> contractCreate( - MINT_CONTRACT, HapiParserUtil.asHeadlongAddress(asAddress(fungible.get()))))) - .when(withOpContext((spec, opLog) -> allRunFor( + return hapiTest( + cryptoCreate(TOKEN_TREASURY), + cryptoCreate(SIGNER).balance(ONE_MILLION_HBARS), + tokenCreate(FUNGIBLE_TOKEN) + .tokenType(TokenType.FUNGIBLE_COMMON) + .initialSupply(initialAmount) + .treasury(TOKEN_TREASURY) + .adminKey(TOKEN_TREASURY) + .supplyKey(TOKEN_TREASURY) + .exposingCreatedIdTo(idLit -> fungible.set(asToken(idLit))), + uploadInitCode(MIXED_BURN_TOKEN), + uploadInitCode(MINT_CONTRACT), + sourcing(() -> + contractCreate(MINT_CONTRACT, HapiParserUtil.asHeadlongAddress(asAddress(fungible.get())))), + withOpContext((spec, opLog) -> allRunFor( spec, contractCreate(MIXED_BURN_TOKEN, HapiParserUtil.asHeadlongAddress(asAddress(fungible.get()))), // Test Case 1: Signer paying and signing a token burn transaction, @@ -373,18 +368,17 @@ final Stream V2Security004FungibleTokenBurnNegative() { getTokenInfo(FUNGIBLE_TOKEN).hasTotalSupply(initialAmount), getTxnRecord(TOKEN_HAS_NO_UPDATED_KEY) .andAllChildRecords() - .logged()))) - .then( - // Verify that the child records fail with the expected status - getTxnRecord(SIGNER_AND_TOKEN_HAVE_NO_UPDATED_KEYS) - .andAllChildRecords() - .hasChildRecords(recordWith().status(INVALID_FULL_PREFIX_SIGNATURE_FOR_PRECOMPILE)), - getTxnRecord(SIGNER_MINTS_WITH_SIGNER_PUBLIC_KEY_AND_WRONG_CONTRACT_ID) - .andAllChildRecords() - .hasChildRecords(recordWith().status(INVALID_FULL_PREFIX_SIGNATURE_FOR_PRECOMPILE)), - getTxnRecord(TOKEN_HAS_NO_UPDATED_KEY) - .andAllChildRecords() - .hasChildRecords(recordWith().status(INVALID_FULL_PREFIX_SIGNATURE_FOR_PRECOMPILE))); + .logged())), + // Verify that the child records fail with the expected status + getTxnRecord(SIGNER_AND_TOKEN_HAVE_NO_UPDATED_KEYS) + .andAllChildRecords() + .hasChildRecords(recordWith().status(INVALID_FULL_PREFIX_SIGNATURE_FOR_PRECOMPILE)), + getTxnRecord(SIGNER_MINTS_WITH_SIGNER_PUBLIC_KEY_AND_WRONG_CONTRACT_ID) + .andAllChildRecords() + .hasChildRecords(recordWith().status(INVALID_FULL_PREFIX_SIGNATURE_FOR_PRECOMPILE)), + getTxnRecord(TOKEN_HAS_NO_UPDATED_KEY) + .andAllChildRecords() + .hasChildRecords(recordWith().status(INVALID_FULL_PREFIX_SIGNATURE_FOR_PRECOMPILE))); } @HapiTest @@ -392,25 +386,24 @@ final Stream V2Security004NonFungibleTokenBurnNegative() { final AtomicReference nonFungible = new AtomicReference<>(); final var serialNumber1 = new long[] {1L}; - return defaultHapiSpec("V2Security004NonFungibleTokenBurnNegative") - .given( - cryptoCreate(TOKEN_TREASURY), - cryptoCreate(SIGNER).balance(ONE_MILLION_HBARS), - tokenCreate(NON_FUNGIBLE_TOKEN) - .tokenType(TokenType.NON_FUNGIBLE_UNIQUE) - .initialSupply(0) - .treasury(TOKEN_TREASURY) - .adminKey(TOKEN_TREASURY) - .supplyKey(TOKEN_TREASURY) - .exposingCreatedIdTo(idLit -> nonFungible.set(asToken(idLit))), - // Mint NFT, so that we can verify that the burn fails as expected - mintToken(NON_FUNGIBLE_TOKEN, List.of(copyFromUtf8(FIRST))), - uploadInitCode(MIXED_BURN_TOKEN), - // contractCreate(MIXED_BURN_TOKEN), - uploadInitCode(MINT_CONTRACT), - sourcing(() -> contractCreate( - MINT_CONTRACT, HapiParserUtil.asHeadlongAddress(asAddress(nonFungible.get()))))) - .when(withOpContext((spec, opLog) -> allRunFor( + return hapiTest( + cryptoCreate(TOKEN_TREASURY), + cryptoCreate(SIGNER).balance(ONE_MILLION_HBARS), + tokenCreate(NON_FUNGIBLE_TOKEN) + .tokenType(TokenType.NON_FUNGIBLE_UNIQUE) + .initialSupply(0) + .treasury(TOKEN_TREASURY) + .adminKey(TOKEN_TREASURY) + .supplyKey(TOKEN_TREASURY) + .exposingCreatedIdTo(idLit -> nonFungible.set(asToken(idLit))), + // Mint NFT, so that we can verify that the burn fails as expected + mintToken(NON_FUNGIBLE_TOKEN, List.of(copyFromUtf8(FIRST))), + uploadInitCode(MIXED_BURN_TOKEN), + // contractCreate(MIXED_BURN_TOKEN), + uploadInitCode(MINT_CONTRACT), + sourcing(() -> + contractCreate(MINT_CONTRACT, HapiParserUtil.asHeadlongAddress(asAddress(nonFungible.get())))), + withOpContext((spec, opLog) -> allRunFor( spec, contractCreate( MIXED_BURN_TOKEN, HapiParserUtil.asHeadlongAddress(asAddress(nonFungible.get()))), @@ -479,36 +472,34 @@ final Stream V2Security004NonFungibleTokenBurnNegative() { getTokenInfo(NON_FUNGIBLE_TOKEN).hasTotalSupply(1L), getTxnRecord(TOKEN_HAS_NO_UPDATED_KEY) .andAllChildRecords() - .logged()))) - .then( - // Verify that the child records fail with the expected status - getTxnRecord(SIGNER_AND_TOKEN_HAVE_NO_UPDATED_KEYS) - .andAllChildRecords() - .hasChildRecords(recordWith().status(INVALID_FULL_PREFIX_SIGNATURE_FOR_PRECOMPILE)), - getTxnRecord(SIGNER_MINTS_WITH_SIGNER_PUBLIC_KEY_AND_WRONG_CONTRACT_ID) - .andAllChildRecords() - .hasChildRecords(recordWith().status(INVALID_FULL_PREFIX_SIGNATURE_FOR_PRECOMPILE)), - getTxnRecord(TOKEN_HAS_NO_UPDATED_KEY) - .andAllChildRecords() - .hasChildRecords(recordWith().status(INVALID_FULL_PREFIX_SIGNATURE_FOR_PRECOMPILE))); + .logged())), + // Verify that the child records fail with the expected status + getTxnRecord(SIGNER_AND_TOKEN_HAVE_NO_UPDATED_KEYS) + .andAllChildRecords() + .hasChildRecords(recordWith().status(INVALID_FULL_PREFIX_SIGNATURE_FOR_PRECOMPILE)), + getTxnRecord(SIGNER_MINTS_WITH_SIGNER_PUBLIC_KEY_AND_WRONG_CONTRACT_ID) + .andAllChildRecords() + .hasChildRecords(recordWith().status(INVALID_FULL_PREFIX_SIGNATURE_FOR_PRECOMPILE)), + getTxnRecord(TOKEN_HAS_NO_UPDATED_KEY) + .andAllChildRecords() + .hasChildRecords(recordWith().status(INVALID_FULL_PREFIX_SIGNATURE_FOR_PRECOMPILE))); } @HapiTest final Stream V2Security039NonFungibleTokenWithDelegateContractKeyCanNotBurnFromDelegatecall() { final var serialNumber1 = new long[] {1L}; - return defaultHapiSpec("V2Security035NonFungibleTokenWithDelegateContractKeyCanNotBurnFromDelegatecall") - .given( - cryptoCreate(TOKEN_TREASURY), - cryptoCreate(SIGNER).balance(ONE_MILLION_HBARS), - tokenCreate(NON_FUNGIBLE_TOKEN) - .tokenType(TokenType.NON_FUNGIBLE_UNIQUE) - .initialSupply(0) - .treasury(TOKEN_TREASURY) - .adminKey(TOKEN_TREASURY) - .supplyKey(TOKEN_TREASURY), - mintToken(NON_FUNGIBLE_TOKEN, List.of(copyFromUtf8(FIRST))), - uploadInitCode(MIXED_BURN_TOKEN)) - .when(withOpContext((spec, opLog) -> allRunFor( + return hapiTest( + cryptoCreate(TOKEN_TREASURY), + cryptoCreate(SIGNER).balance(ONE_MILLION_HBARS), + tokenCreate(NON_FUNGIBLE_TOKEN) + .tokenType(TokenType.NON_FUNGIBLE_UNIQUE) + .initialSupply(0) + .treasury(TOKEN_TREASURY) + .adminKey(TOKEN_TREASURY) + .supplyKey(TOKEN_TREASURY), + mintToken(NON_FUNGIBLE_TOKEN, List.of(copyFromUtf8(FIRST))), + uploadInitCode(MIXED_BURN_TOKEN), + withOpContext((spec, opLog) -> allRunFor( spec, contractCreate( MIXED_BURN_TOKEN, @@ -567,8 +558,8 @@ final Stream V2Security039NonFungibleTokenWithDelegateContractKeyCa // Assert that the token is NOT burned getTokenInfo(NON_FUNGIBLE_TOKEN).hasTotalSupply(1L), // Assert the token is NOT burned from the token treasury account - getAccountBalance(TOKEN_TREASURY).hasTokenBalance(NON_FUNGIBLE_TOKEN, 1L)))) - .then(withOpContext((spec, opLog) -> { + getAccountBalance(TOKEN_TREASURY).hasTokenBalance(NON_FUNGIBLE_TOKEN, 1L))), + withOpContext((spec, opLog) -> { allRunFor( spec, // Verify that each test case has 1 top level call with the correct status @@ -585,18 +576,17 @@ final Stream V2Security039NonFungibleTokenWithDelegateContractKeyCa @HapiTest final Stream V2Security039FungibleTokenWithDelegateContractKeyCanNotBurnFromDelegatecall() { final var initialAmount = 20L; - return defaultHapiSpec("V2Security035FungibleTokenWithDelegateContractKeyCanNotBurnFromDelegatecall") - .given( - cryptoCreate(TOKEN_TREASURY), - cryptoCreate(SIGNER).balance(ONE_MILLION_HBARS), - tokenCreate(FUNGIBLE_TOKEN) - .tokenType(TokenType.FUNGIBLE_COMMON) - .initialSupply(initialAmount) - .treasury(TOKEN_TREASURY) - .adminKey(TOKEN_TREASURY) - .supplyKey(TOKEN_TREASURY), - uploadInitCode(MIXED_BURN_TOKEN)) - .when(withOpContext((spec, opLog) -> allRunFor( + return hapiTest( + cryptoCreate(TOKEN_TREASURY), + cryptoCreate(SIGNER).balance(ONE_MILLION_HBARS), + tokenCreate(FUNGIBLE_TOKEN) + .tokenType(TokenType.FUNGIBLE_COMMON) + .initialSupply(initialAmount) + .treasury(TOKEN_TREASURY) + .adminKey(TOKEN_TREASURY) + .supplyKey(TOKEN_TREASURY), + uploadInitCode(MIXED_BURN_TOKEN), + withOpContext((spec, opLog) -> allRunFor( spec, contractCreate( MIXED_BURN_TOKEN, @@ -645,8 +635,8 @@ final Stream V2Security039FungibleTokenWithDelegateContractKeyCanNo // Assert that the token is NOT burned getTokenInfo(FUNGIBLE_TOKEN).hasTotalSupply(initialAmount), // Assert the token is NOT burned from the token treasury account - getAccountBalance(TOKEN_TREASURY).hasTokenBalance(FUNGIBLE_TOKEN, initialAmount)))) - .then(withOpContext((spec, opLog) -> { + getAccountBalance(TOKEN_TREASURY).hasTokenBalance(FUNGIBLE_TOKEN, initialAmount))), + withOpContext((spec, opLog) -> { allRunFor( spec, // Verify that each test case has 1 top level call with the correct status @@ -667,30 +657,28 @@ final Stream V2SecurityBurnTokenWithFullPrefixAndPartialPrefixKeys( final var amount = 99L; final AtomicLong fungibleNum = new AtomicLong(); - return defaultHapiSpec("burnTokenWithFullPrefixAndPartialPrefixKeys") - .given( - newKeyNamed(SIGNER), - uploadInitCode(ORDINARY_CALLS_CONTRACT), - contractCreate(ORDINARY_CALLS_CONTRACT), - newKeyNamed(THRESHOLD_KEY) - .shape(THRESHOLD_KEY_SHAPE.signedWith(sigs(ON, ORDINARY_CALLS_CONTRACT))), - cryptoCreate(ACCOUNT_NAME).balance(10 * ONE_HUNDRED_HBARS), - cryptoCreate(TOKEN_TREASURY), - tokenCreate(FUNGIBLE_TOKEN) - .tokenType(TokenType.FUNGIBLE_COMMON) - .initialSupply(100) - .treasury(TOKEN_TREASURY) - .adminKey(SIGNER) - .supplyKey(THRESHOLD_KEY) - .exposingCreatedIdTo(idLit -> fungibleNum.set(asDotDelimitedLongArray(idLit)[2])), - tokenCreate(FUNGIBLE_TOKEN_2) - .tokenType(TokenType.FUNGIBLE_COMMON) - .initialSupply(100) - .treasury(TOKEN_TREASURY) - .adminKey(SIGNER) - .supplyKey(SIGNER) - .exposingCreatedIdTo(idLit -> fungibleNum.set(asDotDelimitedLongArray(idLit)[2]))) - .when(withOpContext((spec, opLog) -> allRunFor( + return hapiTest( + newKeyNamed(SIGNER), + uploadInitCode(ORDINARY_CALLS_CONTRACT), + contractCreate(ORDINARY_CALLS_CONTRACT), + newKeyNamed(THRESHOLD_KEY).shape(THRESHOLD_KEY_SHAPE.signedWith(sigs(ON, ORDINARY_CALLS_CONTRACT))), + cryptoCreate(ACCOUNT_NAME).balance(10 * ONE_HUNDRED_HBARS), + cryptoCreate(TOKEN_TREASURY), + tokenCreate(FUNGIBLE_TOKEN) + .tokenType(TokenType.FUNGIBLE_COMMON) + .initialSupply(100) + .treasury(TOKEN_TREASURY) + .adminKey(SIGNER) + .supplyKey(THRESHOLD_KEY) + .exposingCreatedIdTo(idLit -> fungibleNum.set(asDotDelimitedLongArray(idLit)[2])), + tokenCreate(FUNGIBLE_TOKEN_2) + .tokenType(TokenType.FUNGIBLE_COMMON) + .initialSupply(100) + .treasury(TOKEN_TREASURY) + .adminKey(SIGNER) + .supplyKey(SIGNER) + .exposingCreatedIdTo(idLit -> fungibleNum.set(asDotDelimitedLongArray(idLit)[2])), + withOpContext((spec, opLog) -> allRunFor( spec, contractCall( ORDINARY_CALLS_CONTRACT, @@ -713,30 +701,29 @@ final Stream V2SecurityBurnTokenWithFullPrefixAndPartialPrefixKeys( .via(secondBurnTxn) .payingWith(ACCOUNT_NAME) .alsoSigningWithFullPrefix(SIGNER, THRESHOLD_KEY, ACCOUNT_NAME) - .hasKnownStatus(SUCCESS)))) - .then( - childRecordsCheck( - firstBurnTxn, - SUCCESS, - recordWith() - .status(INVALID_FULL_PREFIX_SIGNATURE_FOR_PRECOMPILE) - .contractCallResult(resultWith() - .contractCallResult(htsPrecompileResult() - .forFunction(ParsingConstants.FunctionType.HAPI_BURN) - .withStatus(INVALID_FULL_PREFIX_SIGNATURE_FOR_PRECOMPILE)))), - childRecordsCheck( - secondBurnTxn, - SUCCESS, - recordWith() - .status(SUCCESS) - .contractCallResult(resultWith() - .contractCallResult(htsPrecompileResult() - .forFunction(ParsingConstants.FunctionType.HAPI_BURN) - .withStatus(SUCCESS) - .withTotalSupply(99))) - .newTotalSupply(99)), - getTokenInfo(FUNGIBLE_TOKEN).hasTotalSupply(amount), - getAccountBalance(TOKEN_TREASURY).hasTokenBalance(FUNGIBLE_TOKEN, amount)); + .hasKnownStatus(SUCCESS))), + childRecordsCheck( + firstBurnTxn, + SUCCESS, + recordWith() + .status(INVALID_FULL_PREFIX_SIGNATURE_FOR_PRECOMPILE) + .contractCallResult(resultWith() + .contractCallResult(htsPrecompileResult() + .forFunction(ParsingConstants.FunctionType.HAPI_BURN) + .withStatus(INVALID_FULL_PREFIX_SIGNATURE_FOR_PRECOMPILE)))), + childRecordsCheck( + secondBurnTxn, + SUCCESS, + recordWith() + .status(SUCCESS) + .contractCallResult(resultWith() + .contractCallResult(htsPrecompileResult() + .forFunction(ParsingConstants.FunctionType.HAPI_BURN) + .withStatus(SUCCESS) + .withTotalSupply(99))) + .newTotalSupply(99)), + getTokenInfo(FUNGIBLE_TOKEN).hasTotalSupply(amount), + getAccountBalance(TOKEN_TREASURY).hasTokenBalance(FUNGIBLE_TOKEN, amount)); } @HapiTest @@ -748,80 +735,77 @@ final Stream V2SecurityHscsPreC020RollbackBurnThatFailsAfterAPrecom final var SUPPLY_KEY = "SUPPLY_KEY"; final var ADMIN_KEY = "ADMIN_KEY"; - return defaultHapiSpec("hscsPreC020RollbackBurnThatFailsAfterAPrecompileTransfer") - .given( - newKeyNamed(SUPPLY_KEY), - cryptoCreate(ADMIN_KEY).balance(ONE_HUNDRED_HBARS), - cryptoCreate(ALICE).balance(ONE_HUNDRED_HBARS), - cryptoCreate(bob).balance(ONE_HUNDRED_HBARS), - cryptoCreate(TOKEN_TREASURY).balance(ONE_HUNDRED_HBARS), - cryptoCreate(feeCollector).balance(0L), - tokenCreate(tokenWithHbarFee) - .tokenType(TokenType.NON_FUNGIBLE_UNIQUE) - .supplyKey(SUPPLY_KEY) - .adminKey(ADMIN_KEY) - .initialSupply(0L) - .treasury(TOKEN_TREASURY) - .withCustom(fixedHbarFee(300 * ONE_HBAR, feeCollector)), - mintToken(tokenWithHbarFee, List.of(copyFromUtf8(FIRST))), - mintToken(tokenWithHbarFee, List.of(copyFromUtf8(SECOND))), - uploadInitCode(theContract), - withOpContext((spec, opLog) -> allRunFor( - spec, - contractCreate( - theContract, - asHeadlongAddress(asHexedAddress( - spec.registry().getTokenID(tokenWithHbarFee)))) - .payingWith(bob) - .gas(GAS_TO_OFFER))), - newKeyNamed(THRESHOLD_KEY).shape(THRESHOLD_KEY_SHAPE.signedWith(sigs(ON, theContract))), - tokenUpdate(tokenWithHbarFee).supplyKey(THRESHOLD_KEY).signedByPayerAnd(ADMIN_KEY), - tokenAssociate(ALICE, tokenWithHbarFee), - tokenAssociate(bob, tokenWithHbarFee), - tokenAssociate(theContract, tokenWithHbarFee), - cryptoTransfer(movingUnique(tokenWithHbarFee, 2L).between(TOKEN_TREASURY, ALICE)) - .payingWith(GENESIS), - getAccountInfo(feeCollector) - .has(AccountInfoAsserts.accountWith().balance(0L))) - .when( - withOpContext((spec, opLog) -> { - final var serialNumbers = new long[] {1L}; - allRunFor( - spec, - contractCall( - theContract, - "transferBurn", - HapiParserUtil.asHeadlongAddress(asAddress( - spec.registry().getAccountID(ALICE))), - HapiParserUtil.asHeadlongAddress(asAddress( - spec.registry().getAccountID(bob))), - BigInteger.ZERO, - 2L, - serialNumbers) - .alsoSigningWithFullPrefix(ALICE, THRESHOLD_KEY) - .gas(GAS_TO_OFFER) - .via("contractCallTxn") - .hasKnownStatus(CONTRACT_REVERT_EXECUTED)); - }), - childRecordsCheck( - "contractCallTxn", - CONTRACT_REVERT_EXECUTED, - recordWith() - .status(REVERTED_SUCCESS) - .contractCallResult(resultWith() - .contractCallResult(htsPrecompileResult() - .forFunction(ParsingConstants.FunctionType.HAPI_BURN) - .withStatus(SUCCESS) - .withTotalSupply(1))), - recordWith() - .status(SPENDER_DOES_NOT_HAVE_ALLOWANCE) - .contractCallResult(resultWith() - .contractCallResult(htsPrecompileResult() - .withStatus(SPENDER_DOES_NOT_HAVE_ALLOWANCE))))) - .then( - getAccountBalance(bob).hasTokenBalance(tokenWithHbarFee, 0), - getAccountBalance(TOKEN_TREASURY).hasTokenBalance(tokenWithHbarFee, 1), - getAccountBalance(ALICE).hasTokenBalance(tokenWithHbarFee, 1)); + return hapiTest( + newKeyNamed(SUPPLY_KEY), + cryptoCreate(ADMIN_KEY).balance(ONE_HUNDRED_HBARS), + cryptoCreate(ALICE).balance(ONE_HUNDRED_HBARS), + cryptoCreate(bob).balance(ONE_HUNDRED_HBARS), + cryptoCreate(TOKEN_TREASURY).balance(ONE_HUNDRED_HBARS), + cryptoCreate(feeCollector).balance(0L), + tokenCreate(tokenWithHbarFee) + .tokenType(TokenType.NON_FUNGIBLE_UNIQUE) + .supplyKey(SUPPLY_KEY) + .adminKey(ADMIN_KEY) + .initialSupply(0L) + .treasury(TOKEN_TREASURY) + .withCustom(fixedHbarFee(300 * ONE_HBAR, feeCollector)), + mintToken(tokenWithHbarFee, List.of(copyFromUtf8(FIRST))), + mintToken(tokenWithHbarFee, List.of(copyFromUtf8(SECOND))), + uploadInitCode(theContract), + withOpContext((spec, opLog) -> allRunFor( + spec, + contractCreate( + theContract, + asHeadlongAddress( + asHexedAddress(spec.registry().getTokenID(tokenWithHbarFee)))) + .payingWith(bob) + .gas(GAS_TO_OFFER))), + newKeyNamed(THRESHOLD_KEY).shape(THRESHOLD_KEY_SHAPE.signedWith(sigs(ON, theContract))), + tokenUpdate(tokenWithHbarFee).supplyKey(THRESHOLD_KEY).signedByPayerAnd(ADMIN_KEY), + tokenAssociate(ALICE, tokenWithHbarFee), + tokenAssociate(bob, tokenWithHbarFee), + tokenAssociate(theContract, tokenWithHbarFee), + cryptoTransfer(movingUnique(tokenWithHbarFee, 2L).between(TOKEN_TREASURY, ALICE)) + .payingWith(GENESIS), + getAccountInfo(feeCollector) + .has(AccountInfoAsserts.accountWith().balance(0L)), + withOpContext((spec, opLog) -> { + final var serialNumbers = new long[] {1L}; + allRunFor( + spec, + contractCall( + theContract, + "transferBurn", + HapiParserUtil.asHeadlongAddress( + asAddress(spec.registry().getAccountID(ALICE))), + HapiParserUtil.asHeadlongAddress( + asAddress(spec.registry().getAccountID(bob))), + BigInteger.ZERO, + 2L, + serialNumbers) + .alsoSigningWithFullPrefix(ALICE, THRESHOLD_KEY) + .gas(GAS_TO_OFFER) + .via("contractCallTxn") + .hasKnownStatus(CONTRACT_REVERT_EXECUTED)); + }), + childRecordsCheck( + "contractCallTxn", + CONTRACT_REVERT_EXECUTED, + recordWith() + .status(REVERTED_SUCCESS) + .contractCallResult(resultWith() + .contractCallResult(htsPrecompileResult() + .forFunction(ParsingConstants.FunctionType.HAPI_BURN) + .withStatus(SUCCESS) + .withTotalSupply(1))), + recordWith() + .status(SPENDER_DOES_NOT_HAVE_ALLOWANCE) + .contractCallResult(resultWith() + .contractCallResult( + htsPrecompileResult().withStatus(SPENDER_DOES_NOT_HAVE_ALLOWANCE)))), + getAccountBalance(bob).hasTokenBalance(tokenWithHbarFee, 0), + getAccountBalance(TOKEN_TREASURY).hasTokenBalance(tokenWithHbarFee, 1), + getAccountBalance(ALICE).hasTokenBalance(tokenWithHbarFee, 1)); } @HapiTest @@ -830,82 +814,80 @@ final Stream V2SecurityHscsPrec004TokenBurnOfFungibleTokenUnits() { final var CREATION_TX = "CREATION_TX"; final var MULTI_KEY = "MULTI_KEY"; - return defaultHapiSpec("V2SecurityHscsPrec004TokenBurnOfFungibleTokenUnits") - .given( - newKeyNamed(MULTI_KEY), - newKeyNamed(ADMIN_KEY), - cryptoCreate(ALICE).balance(10 * ONE_HUNDRED_HBARS), - cryptoCreate(TOKEN_TREASURY), - tokenCreate(FUNGIBLE_TOKEN) - .tokenType(TokenType.FUNGIBLE_COMMON) - .initialSupply(50L) - .supplyKey(MULTI_KEY) - .adminKey(ADMIN_KEY) - .treasury(TOKEN_TREASURY), - uploadInitCode(MIXED_BURN_TOKEN), - withOpContext((spec, opLog) -> allRunFor( - spec, - contractCreate( - MIXED_BURN_TOKEN, - asHeadlongAddress(asHexedAddress( - spec.registry().getTokenID(FUNGIBLE_TOKEN)))) - .payingWith(ALICE) - .via(CREATION_TX) - .gas(GAS_TO_OFFER))), - newKeyNamed(THRESHOLD_KEY).shape(THRESHOLD_KEY_SHAPE.signedWith(sigs(ON, MIXED_BURN_TOKEN))), - tokenUpdate(FUNGIBLE_TOKEN).supplyKey(THRESHOLD_KEY).signedByPayerAnd(ADMIN_KEY), - getTxnRecord(CREATION_TX).logged()) - .when( - contractCall(MIXED_BURN_TOKEN, BURN_TOKEN_WITH_EVENT, BigInteger.ZERO, new long[0]) - .payingWith(ALICE) - .alsoSigningWithFullPrefix(THRESHOLD_KEY) - .gas(GAS_TO_OFFER) - .via("burnZero"), - getAccountBalance(TOKEN_TREASURY).hasTokenBalance(FUNGIBLE_TOKEN, 50), - contractCall(MIXED_BURN_TOKEN, BURN_TOKEN_WITH_EVENT, BigInteger.ONE, new long[0]) + return hapiTest( + newKeyNamed(MULTI_KEY), + newKeyNamed(ADMIN_KEY), + cryptoCreate(ALICE).balance(10 * ONE_HUNDRED_HBARS), + cryptoCreate(TOKEN_TREASURY), + tokenCreate(FUNGIBLE_TOKEN) + .tokenType(TokenType.FUNGIBLE_COMMON) + .initialSupply(50L) + .supplyKey(MULTI_KEY) + .adminKey(ADMIN_KEY) + .treasury(TOKEN_TREASURY), + uploadInitCode(MIXED_BURN_TOKEN), + withOpContext((spec, opLog) -> allRunFor( + spec, + contractCreate( + MIXED_BURN_TOKEN, + asHeadlongAddress( + asHexedAddress(spec.registry().getTokenID(FUNGIBLE_TOKEN)))) .payingWith(ALICE) - .alsoSigningWithFullPrefix(THRESHOLD_KEY) - .gas(GAS_TO_OFFER) - .via("burn"), - getTxnRecord("burn") - .hasPriority(recordWith() - .contractCallResult(resultWith() - .logs(inOrder(logWith() - .noData() - .withTopicsInOrder(List.of(parsedToByteString(49))))))), - getAccountBalance(TOKEN_TREASURY).hasTokenBalance(FUNGIBLE_TOKEN, 49), - childRecordsCheck( - "burn", - SUCCESS, - recordWith() - .status(SUCCESS) - .contractCallResult(resultWith() - .contractCallResult(htsPrecompileResult() - .forFunction(ParsingConstants.FunctionType.HAPI_BURN) - .withStatus(SUCCESS) - .withTotalSupply(49)) - .gasUsed(gasUsed)) - .newTotalSupply(49) - .tokenTransfers(changingFungibleBalances() - .including(FUNGIBLE_TOKEN, TOKEN_TREASURY, -1)) - .newTotalSupply(49)), - contractCall(MIXED_BURN_TOKEN, "burnToken", BigInteger.ONE, new long[0]) - .via("burn with contract key") - .gas(GAS_TO_OFFER), - childRecordsCheck( - "burn with contract key", - SUCCESS, - recordWith() - .status(SUCCESS) - .contractCallResult(resultWith() - .contractCallResult(htsPrecompileResult() - .forFunction(ParsingConstants.FunctionType.HAPI_BURN) - .withStatus(SUCCESS) - .withTotalSupply(48))) - .newTotalSupply(48) - .tokenTransfers(changingFungibleBalances() - .including(FUNGIBLE_TOKEN, TOKEN_TREASURY, -1)))) - .then(getAccountBalance(TOKEN_TREASURY).hasTokenBalance(FUNGIBLE_TOKEN, 48)); + .via(CREATION_TX) + .gas(GAS_TO_OFFER))), + newKeyNamed(THRESHOLD_KEY).shape(THRESHOLD_KEY_SHAPE.signedWith(sigs(ON, MIXED_BURN_TOKEN))), + tokenUpdate(FUNGIBLE_TOKEN).supplyKey(THRESHOLD_KEY).signedByPayerAnd(ADMIN_KEY), + getTxnRecord(CREATION_TX).logged(), + contractCall(MIXED_BURN_TOKEN, BURN_TOKEN_WITH_EVENT, BigInteger.ZERO, new long[0]) + .payingWith(ALICE) + .alsoSigningWithFullPrefix(THRESHOLD_KEY) + .gas(GAS_TO_OFFER) + .via("burnZero"), + getAccountBalance(TOKEN_TREASURY).hasTokenBalance(FUNGIBLE_TOKEN, 50), + contractCall(MIXED_BURN_TOKEN, BURN_TOKEN_WITH_EVENT, BigInteger.ONE, new long[0]) + .payingWith(ALICE) + .alsoSigningWithFullPrefix(THRESHOLD_KEY) + .gas(GAS_TO_OFFER) + .via("burn"), + getTxnRecord("burn") + .hasPriority(recordWith() + .contractCallResult(resultWith() + .logs(inOrder(logWith() + .noData() + .withTopicsInOrder(List.of(parsedToByteString(49))))))), + getAccountBalance(TOKEN_TREASURY).hasTokenBalance(FUNGIBLE_TOKEN, 49), + childRecordsCheck( + "burn", + SUCCESS, + recordWith() + .status(SUCCESS) + .contractCallResult(resultWith() + .contractCallResult(htsPrecompileResult() + .forFunction(ParsingConstants.FunctionType.HAPI_BURN) + .withStatus(SUCCESS) + .withTotalSupply(49)) + .gasUsed(gasUsed)) + .newTotalSupply(49) + .tokenTransfers( + changingFungibleBalances().including(FUNGIBLE_TOKEN, TOKEN_TREASURY, -1)) + .newTotalSupply(49)), + contractCall(MIXED_BURN_TOKEN, "burnToken", BigInteger.ONE, new long[0]) + .via("burn with contract key") + .gas(GAS_TO_OFFER), + childRecordsCheck( + "burn with contract key", + SUCCESS, + recordWith() + .status(SUCCESS) + .contractCallResult(resultWith() + .contractCallResult(htsPrecompileResult() + .forFunction(ParsingConstants.FunctionType.HAPI_BURN) + .withStatus(SUCCESS) + .withTotalSupply(48))) + .newTotalSupply(48) + .tokenTransfers( + changingFungibleBalances().including(FUNGIBLE_TOKEN, TOKEN_TREASURY, -1))), + getAccountBalance(TOKEN_TREASURY).hasTokenBalance(FUNGIBLE_TOKEN, 48)); } @HapiTest @@ -917,131 +899,121 @@ final Stream V2SecurityHscsPrec011BurnAfterNestedMint() { final var CREATION_TX = "CREATION_TX"; final var BURN_AFTER_NESTED_MINT_TX = "burnAfterNestedMint"; - return defaultHapiSpec("V2SecurityHscsPrec011BurnAfterNestedMint") - .given( - newKeyNamed(SUPPLY_KEY), - newKeyNamed(ADMIN_KEY), - cryptoCreate(ALICE).balance(10 * ONE_HUNDRED_HBARS), - cryptoCreate(TOKEN_TREASURY), - tokenCreate(FUNGIBLE_TOKEN) - .tokenType(TokenType.FUNGIBLE_COMMON) - .initialSupply(50L) - .supplyKey(SUPPLY_KEY) - .adminKey(ADMIN_KEY) - .treasury(TOKEN_TREASURY), - uploadInitCode(innerContract, outerContract), - contractCreate(innerContract).gas(GAS_TO_OFFER), - withOpContext((spec, opLog) -> allRunFor( - spec, - contractCreate( - outerContract, - asHeadlongAddress(getNestedContractAddress(innerContract, spec))) - .payingWith(ALICE) - .via(CREATION_TX) - .gas(GAS_TO_OFFER))), - newKeyNamed(THRESHOLD_KEY).shape(THRESHOLD_KEY_SHAPE.signedWith(sigs(ON, outerContract))), - tokenUpdate(FUNGIBLE_TOKEN).supplyKey(THRESHOLD_KEY).signedByPayerAnd(ADMIN_KEY), - getTxnRecord(CREATION_TX).logged()) - .when( - withOpContext((spec, opLog) -> allRunFor( - spec, - newKeyNamed(CONTRACT_KEY) - .shape(revisedKey.signedWith(sigs(ON, innerContract, outerContract))), - tokenUpdate(FUNGIBLE_TOKEN) - .supplyKey(CONTRACT_KEY) - .signedByPayerAnd(ADMIN_KEY), - contractCall( - outerContract, - BURN_AFTER_NESTED_MINT_TX, - BigInteger.ONE, - HapiParserUtil.asHeadlongAddress(asAddress( - spec.registry().getTokenID(FUNGIBLE_TOKEN))), - new long[0]) - .payingWith(ALICE) - .alsoSigningWithFullPrefix(CONTRACT_KEY) - .hasKnownStatus(SUCCESS) - .via(BURN_AFTER_NESTED_MINT_TX))), - childRecordsCheck( - BURN_AFTER_NESTED_MINT_TX, - SUCCESS, - recordWith() - .status(SUCCESS) - .contractCallResult(resultWith() - .contractCallResult(htsPrecompileResult() - .forFunction(ParsingConstants.FunctionType.HAPI_MINT) - .withStatus(SUCCESS) - .withTotalSupply(51) - .withSerialNumbers())) - .tokenTransfers( - changingFungibleBalances().including(FUNGIBLE_TOKEN, TOKEN_TREASURY, 1)) - .newTotalSupply(51), - recordWith() - .status(SUCCESS) - .contractCallResult(resultWith() - .contractCallResult(htsPrecompileResult() - .forFunction(ParsingConstants.FunctionType.HAPI_BURN) - .withStatus(SUCCESS) - .withTotalSupply(50))) - .tokenTransfers(changingFungibleBalances() - .including(FUNGIBLE_TOKEN, TOKEN_TREASURY, -1)) - .newTotalSupply(50))) - .then(getAccountBalance(TOKEN_TREASURY).hasTokenBalance(FUNGIBLE_TOKEN, 50)); + return hapiTest( + newKeyNamed(SUPPLY_KEY), + newKeyNamed(ADMIN_KEY), + cryptoCreate(ALICE).balance(10 * ONE_HUNDRED_HBARS), + cryptoCreate(TOKEN_TREASURY), + tokenCreate(FUNGIBLE_TOKEN) + .tokenType(TokenType.FUNGIBLE_COMMON) + .initialSupply(50L) + .supplyKey(SUPPLY_KEY) + .adminKey(ADMIN_KEY) + .treasury(TOKEN_TREASURY), + uploadInitCode(innerContract, outerContract), + contractCreate(innerContract).gas(GAS_TO_OFFER), + withOpContext((spec, opLog) -> allRunFor( + spec, + contractCreate(outerContract, asHeadlongAddress(getNestedContractAddress(innerContract, spec))) + .payingWith(ALICE) + .via(CREATION_TX) + .gas(GAS_TO_OFFER))), + newKeyNamed(THRESHOLD_KEY).shape(THRESHOLD_KEY_SHAPE.signedWith(sigs(ON, outerContract))), + tokenUpdate(FUNGIBLE_TOKEN).supplyKey(THRESHOLD_KEY).signedByPayerAnd(ADMIN_KEY), + getTxnRecord(CREATION_TX).logged(), + withOpContext((spec, opLog) -> allRunFor( + spec, + newKeyNamed(CONTRACT_KEY).shape(revisedKey.signedWith(sigs(ON, innerContract, outerContract))), + tokenUpdate(FUNGIBLE_TOKEN).supplyKey(CONTRACT_KEY).signedByPayerAnd(ADMIN_KEY), + contractCall( + outerContract, + BURN_AFTER_NESTED_MINT_TX, + BigInteger.ONE, + HapiParserUtil.asHeadlongAddress( + asAddress(spec.registry().getTokenID(FUNGIBLE_TOKEN))), + new long[0]) + .payingWith(ALICE) + .alsoSigningWithFullPrefix(CONTRACT_KEY) + .hasKnownStatus(SUCCESS) + .via(BURN_AFTER_NESTED_MINT_TX))), + childRecordsCheck( + BURN_AFTER_NESTED_MINT_TX, + SUCCESS, + recordWith() + .status(SUCCESS) + .contractCallResult(resultWith() + .contractCallResult(htsPrecompileResult() + .forFunction(ParsingConstants.FunctionType.HAPI_MINT) + .withStatus(SUCCESS) + .withTotalSupply(51) + .withSerialNumbers())) + .tokenTransfers(changingFungibleBalances().including(FUNGIBLE_TOKEN, TOKEN_TREASURY, 1)) + .newTotalSupply(51), + recordWith() + .status(SUCCESS) + .contractCallResult(resultWith() + .contractCallResult(htsPrecompileResult() + .forFunction(ParsingConstants.FunctionType.HAPI_BURN) + .withStatus(SUCCESS) + .withTotalSupply(50))) + .tokenTransfers( + changingFungibleBalances().including(FUNGIBLE_TOKEN, TOKEN_TREASURY, -1)) + .newTotalSupply(50)), + getAccountBalance(TOKEN_TREASURY).hasTokenBalance(FUNGIBLE_TOKEN, 50)); } @HapiTest final Stream V2SecurityHscsPrec005TokenBurnOfNft() { final var gasUsed = 15284L; final var CREATION_TX = "CREATION_TX"; - return defaultHapiSpec("V2SecurityHscsPrec005TokenBurnOfNft") - .given( - newKeyNamed(ADMIN_KEY), - newKeyNamed(SUPPLY_KEY), - cryptoCreate(ALICE).balance(10 * ONE_HUNDRED_HBARS), - cryptoCreate(TOKEN_TREASURY), - tokenCreate(NON_FUNGIBLE_TOKEN) - .tokenType(TokenType.NON_FUNGIBLE_UNIQUE) - .initialSupply(0L) - .supplyKey(SUPPLY_KEY) - .adminKey(ADMIN_KEY) - .treasury(TOKEN_TREASURY), - mintToken(NON_FUNGIBLE_TOKEN, List.of(copyFromUtf8(FIRST))), - mintToken(NON_FUNGIBLE_TOKEN, List.of(copyFromUtf8(SECOND))), - uploadInitCode(BURN_TOKEN), - withOpContext((spec, opLog) -> allRunFor( - spec, - contractCreate( - BURN_TOKEN, - asHeadlongAddress(asHexedAddress( - spec.registry().getTokenID(NON_FUNGIBLE_TOKEN)))) - .payingWith(ALICE) - .via(CREATION_TX) - .gas(GAS_TO_OFFER))), - newKeyNamed(THRESHOLD_KEY).shape(THRESHOLD_KEY_SHAPE.signedWith(sigs(ON, BURN_TOKEN))), - tokenUpdate(NON_FUNGIBLE_TOKEN).supplyKey(THRESHOLD_KEY).signedByPayerAnd(ADMIN_KEY), - getTxnRecord(CREATION_TX).logged()) - .when( - withOpContext((spec, opLog) -> { - final var serialNumbers = new long[] {1L}; - allRunFor( - spec, - contractCall(BURN_TOKEN, "burnToken", BigInteger.ZERO, serialNumbers) - .payingWith(ALICE) - .alsoSigningWithFullPrefix(THRESHOLD_KEY) - .gas(GAS_TO_OFFER) - .via("burn")); - }), - childRecordsCheck( - "burn", - SUCCESS, - recordWith() - .status(SUCCESS) - .contractCallResult(resultWith() - .contractCallResult(htsPrecompileResult() - .forFunction(ParsingConstants.FunctionType.HAPI_BURN) - .withStatus(SUCCESS) - .withTotalSupply(1)) - .gasUsed(gasUsed)) - .newTotalSupply(1))) - .then(getAccountBalance(TOKEN_TREASURY).hasTokenBalance(NON_FUNGIBLE_TOKEN, 1)); + return hapiTest( + newKeyNamed(ADMIN_KEY), + newKeyNamed(SUPPLY_KEY), + cryptoCreate(ALICE).balance(10 * ONE_HUNDRED_HBARS), + cryptoCreate(TOKEN_TREASURY), + tokenCreate(NON_FUNGIBLE_TOKEN) + .tokenType(TokenType.NON_FUNGIBLE_UNIQUE) + .initialSupply(0L) + .supplyKey(SUPPLY_KEY) + .adminKey(ADMIN_KEY) + .treasury(TOKEN_TREASURY), + mintToken(NON_FUNGIBLE_TOKEN, List.of(copyFromUtf8(FIRST))), + mintToken(NON_FUNGIBLE_TOKEN, List.of(copyFromUtf8(SECOND))), + uploadInitCode(BURN_TOKEN), + withOpContext((spec, opLog) -> allRunFor( + spec, + contractCreate( + BURN_TOKEN, + asHeadlongAddress( + asHexedAddress(spec.registry().getTokenID(NON_FUNGIBLE_TOKEN)))) + .payingWith(ALICE) + .via(CREATION_TX) + .gas(GAS_TO_OFFER))), + newKeyNamed(THRESHOLD_KEY).shape(THRESHOLD_KEY_SHAPE.signedWith(sigs(ON, BURN_TOKEN))), + tokenUpdate(NON_FUNGIBLE_TOKEN).supplyKey(THRESHOLD_KEY).signedByPayerAnd(ADMIN_KEY), + getTxnRecord(CREATION_TX).logged(), + withOpContext((spec, opLog) -> { + final var serialNumbers = new long[] {1L}; + allRunFor( + spec, + contractCall(BURN_TOKEN, "burnToken", BigInteger.ZERO, serialNumbers) + .payingWith(ALICE) + .alsoSigningWithFullPrefix(THRESHOLD_KEY) + .gas(GAS_TO_OFFER) + .via("burn")); + }), + childRecordsCheck( + "burn", + SUCCESS, + recordWith() + .status(SUCCESS) + .contractCallResult(resultWith() + .contractCallResult(htsPrecompileResult() + .forFunction(ParsingConstants.FunctionType.HAPI_BURN) + .withStatus(SUCCESS) + .withTotalSupply(1)) + .gasUsed(gasUsed)) + .newTotalSupply(1)), + getAccountBalance(TOKEN_TREASURY).hasTokenBalance(NON_FUNGIBLE_TOKEN, 1)); } } diff --git a/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/precompile/ContractHTSSuite.java b/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/precompile/ContractHTSSuite.java index 5399a4cdfc91..4342f3a79a87 100644 --- a/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/precompile/ContractHTSSuite.java +++ b/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/precompile/ContractHTSSuite.java @@ -18,7 +18,6 @@ import static com.google.protobuf.ByteString.copyFromUtf8; import static com.hedera.services.bdd.junit.TestTags.SMART_CONTRACT; -import static com.hedera.services.bdd.spec.HapiSpec.defaultHapiSpec; import static com.hedera.services.bdd.spec.HapiSpec.hapiTest; import static com.hedera.services.bdd.spec.assertions.ContractFnResultAsserts.resultWith; import static com.hedera.services.bdd.spec.assertions.TransactionRecordAsserts.recordWith; @@ -357,30 +356,29 @@ final Stream shouldFailWhenTransferringTokensWithInvalidParametersA final var TXN_WITH_INVALID_TOKEN_ADDRESS = "TXN_WITH_INVALID_TOKEN_ADDRESS"; final var TXN_WITH_AMOUNT_BIGGER_THAN_BALANCE = "TXN_WITH_AMOUNT_BIGGER_THAN_BALANCE"; - return defaultHapiSpec("shouldFailWhenTransferringTokensWithInvalidParametersAndConditions") - .given( - newKeyNamed(UNIVERSAL_KEY), - cryptoCreate(ACCOUNT).balance(100 * ONE_HUNDRED_HBARS), - cryptoCreate(RECEIVER), - cryptoCreate(SECOND_RECEIVER), - cryptoCreate(TOKEN_TREASURY), - tokenCreate(FUNGIBLE_TOKEN) - .tokenType(TokenType.FUNGIBLE_COMMON) - .initialSupply(1_000L) - .supplyKey(UNIVERSAL_KEY) - .treasury(TOKEN_TREASURY), - uploadInitCode(TOKEN_TRANSFERS_CONTRACT), - contractCreate(TOKEN_TRANSFERS_CONTRACT).gas(GAS_TO_OFFER), - tokenAssociate(ACCOUNT, FUNGIBLE_TOKEN), - tokenAssociate(RECEIVER, FUNGIBLE_TOKEN), - tokenAssociate(SECOND_RECEIVER, FUNGIBLE_TOKEN), - cryptoApproveAllowance() - .payingWith(DEFAULT_PAYER) - .addTokenAllowance(ACCOUNT, FUNGIBLE_TOKEN, TOKEN_TRANSFERS_CONTRACT, 200L) - .signedBy(DEFAULT_PAYER, ACCOUNT) - .fee(ONE_HBAR), - cryptoTransfer(moving(200L, FUNGIBLE_TOKEN).between(TOKEN_TREASURY, ACCOUNT))) - .when(withOpContext((spec, opLog) -> { + return hapiTest( + newKeyNamed(UNIVERSAL_KEY), + cryptoCreate(ACCOUNT).balance(100 * ONE_HUNDRED_HBARS), + cryptoCreate(RECEIVER), + cryptoCreate(SECOND_RECEIVER), + cryptoCreate(TOKEN_TREASURY), + tokenCreate(FUNGIBLE_TOKEN) + .tokenType(TokenType.FUNGIBLE_COMMON) + .initialSupply(1_000L) + .supplyKey(UNIVERSAL_KEY) + .treasury(TOKEN_TREASURY), + uploadInitCode(TOKEN_TRANSFERS_CONTRACT), + contractCreate(TOKEN_TRANSFERS_CONTRACT).gas(GAS_TO_OFFER), + tokenAssociate(ACCOUNT, FUNGIBLE_TOKEN), + tokenAssociate(RECEIVER, FUNGIBLE_TOKEN), + tokenAssociate(SECOND_RECEIVER, FUNGIBLE_TOKEN), + cryptoApproveAllowance() + .payingWith(DEFAULT_PAYER) + .addTokenAllowance(ACCOUNT, FUNGIBLE_TOKEN, TOKEN_TRANSFERS_CONTRACT, 200L) + .signedBy(DEFAULT_PAYER, ACCOUNT) + .fee(ONE_HBAR), + cryptoTransfer(moving(200L, FUNGIBLE_TOKEN).between(TOKEN_TREASURY, ACCOUNT)), + withOpContext((spec, opLog) -> { final var receiver1 = asAddress(spec.registry().getAccountID(RECEIVER)); final var receiver2 = asAddress(spec.registry().getAccountID(SECOND_RECEIVER)); final var sender = asAddress(spec.registry().getAccountID(ACCOUNT)); @@ -467,20 +465,19 @@ final Stream shouldFailWhenTransferringTokensWithInvalidParametersA .gas(GAS_TO_OFFER) .via(TXN_WITH_AMOUNT_BIGGER_THAN_BALANCE) .hasKnownStatus(CONTRACT_REVERT_EXECUTED)); - })) - .then( - childRecordsCheck( - TXN_WITH_NEGATIVE_AMOUNTS, - CONTRACT_REVERT_EXECUTED, - recordWith().status(TRANSFERS_NOT_ZERO_SUM_FOR_TOKEN)), - childRecordsCheck( - TXN_WITH_INVALID_TOKEN_ADDRESS, - CONTRACT_REVERT_EXECUTED, - recordWith().status(INVALID_TOKEN_ID)), - childRecordsCheck( - TXN_WITH_AMOUNT_BIGGER_THAN_BALANCE, - CONTRACT_REVERT_EXECUTED, - recordWith().status(INSUFFICIENT_TOKEN_BALANCE))); + }), + childRecordsCheck( + TXN_WITH_NEGATIVE_AMOUNTS, + CONTRACT_REVERT_EXECUTED, + recordWith().status(TRANSFERS_NOT_ZERO_SUM_FOR_TOKEN)), + childRecordsCheck( + TXN_WITH_INVALID_TOKEN_ADDRESS, + CONTRACT_REVERT_EXECUTED, + recordWith().status(INVALID_TOKEN_ID)), + childRecordsCheck( + TXN_WITH_AMOUNT_BIGGER_THAN_BALANCE, + CONTRACT_REVERT_EXECUTED, + recordWith().status(INSUFFICIENT_TOKEN_BALANCE))); } @HapiTest @@ -491,28 +488,27 @@ final Stream shouldFailOnInvalidTokenTransferParametersAndCondition final var TXN_WITH_NEGATIVE_AMOUNT = "TXN_WITH_NEGATIVE_AMOUNT"; final var TXN_WITH_AMOUNT_BIGGER_THAN_BALANCE = "TXN_WITH_AMOUNT_BIGGER_THAN_BALANCE"; - return defaultHapiSpec("shouldFailOnInvalidTokenTransferParametersAndConditions") - .given( - newKeyNamed(UNIVERSAL_KEY), - cryptoCreate(ACCOUNT).balance(100 * ONE_HUNDRED_HBARS), - cryptoCreate(RECEIVER), - cryptoCreate(TOKEN_TREASURY), - tokenCreate(FUNGIBLE_TOKEN) - .tokenType(TokenType.FUNGIBLE_COMMON) - .initialSupply(1_000L) - .supplyKey(UNIVERSAL_KEY) - .treasury(TOKEN_TREASURY), - uploadInitCode(TOKEN_TRANSFERS_CONTRACT), - contractCreate(TOKEN_TRANSFERS_CONTRACT).gas(GAS_TO_OFFER), - tokenAssociate(ACCOUNT, FUNGIBLE_TOKEN), - tokenAssociate(RECEIVER, FUNGIBLE_TOKEN), - cryptoApproveAllowance() - .payingWith(DEFAULT_PAYER) - .addTokenAllowance(ACCOUNT, FUNGIBLE_TOKEN, TOKEN_TRANSFERS_CONTRACT, 200L) - .signedBy(DEFAULT_PAYER, ACCOUNT) - .fee(ONE_HBAR), - cryptoTransfer(moving(200L, FUNGIBLE_TOKEN).between(TOKEN_TREASURY, ACCOUNT))) - .when(withOpContext((spec, opLog) -> { + return hapiTest( + newKeyNamed(UNIVERSAL_KEY), + cryptoCreate(ACCOUNT).balance(100 * ONE_HUNDRED_HBARS), + cryptoCreate(RECEIVER), + cryptoCreate(TOKEN_TREASURY), + tokenCreate(FUNGIBLE_TOKEN) + .tokenType(TokenType.FUNGIBLE_COMMON) + .initialSupply(1_000L) + .supplyKey(UNIVERSAL_KEY) + .treasury(TOKEN_TREASURY), + uploadInitCode(TOKEN_TRANSFERS_CONTRACT), + contractCreate(TOKEN_TRANSFERS_CONTRACT).gas(GAS_TO_OFFER), + tokenAssociate(ACCOUNT, FUNGIBLE_TOKEN), + tokenAssociate(RECEIVER, FUNGIBLE_TOKEN), + cryptoApproveAllowance() + .payingWith(DEFAULT_PAYER) + .addTokenAllowance(ACCOUNT, FUNGIBLE_TOKEN, TOKEN_TRANSFERS_CONTRACT, 200L) + .signedBy(DEFAULT_PAYER, ACCOUNT) + .fee(ONE_HBAR), + cryptoTransfer(moving(200L, FUNGIBLE_TOKEN).between(TOKEN_TREASURY, ACCOUNT)), + withOpContext((spec, opLog) -> { final var receiver1 = asHeadlongAddress(asAddress(spec.registry().getAccountID(RECEIVER))); final var sender = @@ -589,16 +585,15 @@ final Stream shouldFailOnInvalidTokenTransferParametersAndCondition .gas(GAS_TO_OFFER) .via(TXN_WITH_AMOUNT_BIGGER_THAN_BALANCE) .hasKnownStatus(CONTRACT_REVERT_EXECUTED)); - })) - .then( - childRecordsCheck( - TXN_WITH_INVALID_TOKEN_ADDRESS, - CONTRACT_REVERT_EXECUTED, - recordWith().status(INVALID_TOKEN_ID)), - childRecordsCheck( - TXN_WITH_AMOUNT_BIGGER_THAN_BALANCE, - CONTRACT_REVERT_EXECUTED, - recordWith().status(INSUFFICIENT_TOKEN_BALANCE))); + }), + childRecordsCheck( + TXN_WITH_INVALID_TOKEN_ADDRESS, + CONTRACT_REVERT_EXECUTED, + recordWith().status(INVALID_TOKEN_ID)), + childRecordsCheck( + TXN_WITH_AMOUNT_BIGGER_THAN_BALANCE, + CONTRACT_REVERT_EXECUTED, + recordWith().status(INSUFFICIENT_TOKEN_BALANCE))); } @HapiTest @@ -611,31 +606,29 @@ final Stream shouldFailWhenTransferringMultipleNFTsWithInvalidParam final var TXN_WITH_INVALID_SERIALS = "TXN_WITH_INVALID_SERIALS"; final var TXN_WITH_NOT_OWNED_NFT = "TXN_WITH_NOT_OWNED_NFT"; - return defaultHapiSpec("shouldFailWhenTransferringMultipleNFTsWithInvalidParametersAndConditions") - .given( - newKeyNamed(UNIVERSAL_KEY), - cryptoCreate(ACCOUNT).balance(100 * ONE_HUNDRED_HBARS), - cryptoCreate(RECEIVER), - cryptoCreate(SECOND_RECEIVER), - cryptoCreate(TOKEN_TREASURY), - tokenCreate(NON_FUNGIBLE_TOKEN) - .tokenType(NON_FUNGIBLE_UNIQUE) - .treasury(TOKEN_TREASURY) - .supplyKey(UNIVERSAL_KEY) - .initialSupply(0), - mintToken(NON_FUNGIBLE_TOKEN, List.of(copyFromUtf8("dark"), copyFromUtf8("matter"))), - tokenAssociate(ACCOUNT, NON_FUNGIBLE_TOKEN), - tokenAssociate(RECEIVER, NON_FUNGIBLE_TOKEN), - cryptoTransfer(movingUnique(NON_FUNGIBLE_TOKEN, 1L, 2L).between(TOKEN_TREASURY, ACCOUNT)), - uploadInitCode(TOKEN_TRANSFERS_CONTRACT), - contractCreate(TOKEN_TRANSFERS_CONTRACT).gas(GAS_TO_OFFER), - cryptoApproveAllowance() - .payingWith(DEFAULT_PAYER) - .addNftAllowance( - ACCOUNT, NON_FUNGIBLE_TOKEN, TOKEN_TRANSFERS_CONTRACT, false, List.of(1L, 2L)) - .signedBy(DEFAULT_PAYER, ACCOUNT) - .fee(ONE_HBAR)) - .when(withOpContext((spec, opLog) -> { + return hapiTest( + newKeyNamed(UNIVERSAL_KEY), + cryptoCreate(ACCOUNT).balance(100 * ONE_HUNDRED_HBARS), + cryptoCreate(RECEIVER), + cryptoCreate(SECOND_RECEIVER), + cryptoCreate(TOKEN_TREASURY), + tokenCreate(NON_FUNGIBLE_TOKEN) + .tokenType(NON_FUNGIBLE_UNIQUE) + .treasury(TOKEN_TREASURY) + .supplyKey(UNIVERSAL_KEY) + .initialSupply(0), + mintToken(NON_FUNGIBLE_TOKEN, List.of(copyFromUtf8("dark"), copyFromUtf8("matter"))), + tokenAssociate(ACCOUNT, NON_FUNGIBLE_TOKEN), + tokenAssociate(RECEIVER, NON_FUNGIBLE_TOKEN), + cryptoTransfer(movingUnique(NON_FUNGIBLE_TOKEN, 1L, 2L).between(TOKEN_TREASURY, ACCOUNT)), + uploadInitCode(TOKEN_TRANSFERS_CONTRACT), + contractCreate(TOKEN_TRANSFERS_CONTRACT).gas(GAS_TO_OFFER), + cryptoApproveAllowance() + .payingWith(DEFAULT_PAYER) + .addNftAllowance(ACCOUNT, NON_FUNGIBLE_TOKEN, TOKEN_TRANSFERS_CONTRACT, false, List.of(1L, 2L)) + .signedBy(DEFAULT_PAYER, ACCOUNT) + .fee(ONE_HBAR), + withOpContext((spec, opLog) -> { final var receiver1 = asAddress(spec.registry().getAccountID(RECEIVER)); final var receiver2 = asAddress(spec.registry().getAccountID(SECOND_RECEIVER)); final var sender = asAddress(spec.registry().getAccountID(ACCOUNT)); @@ -743,20 +736,19 @@ final Stream shouldFailWhenTransferringMultipleNFTsWithInvalidParam .gas(GAS_TO_OFFER) .via(TXN_WITH_NOT_OWNED_NFT) .hasKnownStatus(CONTRACT_REVERT_EXECUTED)); - })) - .then( - childRecordsCheck( - TXN_WITH_INVALID_TOKEN_ADDRESS, - CONTRACT_REVERT_EXECUTED, - recordWith().status(INVALID_TOKEN_ID)), - childRecordsCheck( - TXN_WITH_INVALID_SERIALS, - CONTRACT_REVERT_EXECUTED, - recordWith().status(INVALID_TOKEN_NFT_SERIAL_NUMBER)), - childRecordsCheck( - TXN_WITH_NOT_OWNED_NFT, - CONTRACT_REVERT_EXECUTED, - recordWith().status(SPENDER_DOES_NOT_HAVE_ALLOWANCE))); + }), + childRecordsCheck( + TXN_WITH_INVALID_TOKEN_ADDRESS, + CONTRACT_REVERT_EXECUTED, + recordWith().status(INVALID_TOKEN_ID)), + childRecordsCheck( + TXN_WITH_INVALID_SERIALS, + CONTRACT_REVERT_EXECUTED, + recordWith().status(INVALID_TOKEN_NFT_SERIAL_NUMBER)), + childRecordsCheck( + TXN_WITH_NOT_OWNED_NFT, + CONTRACT_REVERT_EXECUTED, + recordWith().status(SPENDER_DOES_NOT_HAVE_ALLOWANCE))); } @HapiTest @@ -767,30 +759,28 @@ final Stream shouldFailOnInvalidNFTTransferParametersAndConditions( final var TXN_WITH_NEGATIVE_SERIAL = "TXN_WITH_NEGATIVE_SERIAL"; final var TXN_ACCOUNT_DOES_NOT_OWN_NFT = "TXN_ACCOUNT_DOES_NOT_OWN_NFT"; - return defaultHapiSpec("shouldFailOnInvalidNFTTransferParametersAndConditions") - .given( - newKeyNamed(UNIVERSAL_KEY), - cryptoCreate(ACCOUNT).balance(100 * ONE_HUNDRED_HBARS), - cryptoCreate(RECEIVER), - cryptoCreate(TOKEN_TREASURY), - tokenCreate(NON_FUNGIBLE_TOKEN) - .tokenType(NON_FUNGIBLE_UNIQUE) - .treasury(TOKEN_TREASURY) - .supplyKey(UNIVERSAL_KEY) - .initialSupply(0), - mintToken(NON_FUNGIBLE_TOKEN, List.of(copyFromUtf8("dark"), copyFromUtf8("matter"))), - tokenAssociate(ACCOUNT, NON_FUNGIBLE_TOKEN), - tokenAssociate(RECEIVER, NON_FUNGIBLE_TOKEN), - cryptoTransfer(movingUnique(NON_FUNGIBLE_TOKEN, 1L, 2L).between(TOKEN_TREASURY, ACCOUNT)), - uploadInitCode(TOKEN_TRANSFERS_CONTRACT), - contractCreate(TOKEN_TRANSFERS_CONTRACT).gas(GAS_TO_OFFER), - cryptoApproveAllowance() - .payingWith(DEFAULT_PAYER) - .addNftAllowance( - ACCOUNT, NON_FUNGIBLE_TOKEN, TOKEN_TRANSFERS_CONTRACT, false, List.of(1L, 2L)) - .signedBy(DEFAULT_PAYER, ACCOUNT) - .fee(ONE_HBAR)) - .when(withOpContext((spec, opLog) -> { + return hapiTest( + newKeyNamed(UNIVERSAL_KEY), + cryptoCreate(ACCOUNT).balance(100 * ONE_HUNDRED_HBARS), + cryptoCreate(RECEIVER), + cryptoCreate(TOKEN_TREASURY), + tokenCreate(NON_FUNGIBLE_TOKEN) + .tokenType(NON_FUNGIBLE_UNIQUE) + .treasury(TOKEN_TREASURY) + .supplyKey(UNIVERSAL_KEY) + .initialSupply(0), + mintToken(NON_FUNGIBLE_TOKEN, List.of(copyFromUtf8("dark"), copyFromUtf8("matter"))), + tokenAssociate(ACCOUNT, NON_FUNGIBLE_TOKEN), + tokenAssociate(RECEIVER, NON_FUNGIBLE_TOKEN), + cryptoTransfer(movingUnique(NON_FUNGIBLE_TOKEN, 1L, 2L).between(TOKEN_TREASURY, ACCOUNT)), + uploadInitCode(TOKEN_TRANSFERS_CONTRACT), + contractCreate(TOKEN_TRANSFERS_CONTRACT).gas(GAS_TO_OFFER), + cryptoApproveAllowance() + .payingWith(DEFAULT_PAYER) + .addNftAllowance(ACCOUNT, NON_FUNGIBLE_TOKEN, TOKEN_TRANSFERS_CONTRACT, false, List.of(1L, 2L)) + .signedBy(DEFAULT_PAYER, ACCOUNT) + .fee(ONE_HBAR), + withOpContext((spec, opLog) -> { final var receiver1 = asHeadlongAddress(asAddress(spec.registry().getAccountID(RECEIVER))); final var sender = @@ -864,27 +854,26 @@ final Stream shouldFailOnInvalidNFTTransferParametersAndConditions( .gas(GAS_TO_OFFER) .via(TXN_ACCOUNT_DOES_NOT_OWN_NFT) .hasKnownStatus(CONTRACT_REVERT_EXECUTED)); - })) - .then( - childRecordsCheck( - TXN_WITH_INVALID_RECEIVER_ADDRESS, - CONTRACT_REVERT_EXECUTED, - recordWith().status(INVALID_ALIAS_KEY)), - childRecordsCheck( - TXN_WITH_INVALID_SENDER_ADDRESS, - CONTRACT_REVERT_EXECUTED, - recordWith().status(INVALID_ACCOUNT_ID)), - childRecordsCheck( - TXN_WITH_INVALID_TOKEN_ADDRESS, - CONTRACT_REVERT_EXECUTED, - recordWith().status(INVALID_TOKEN_ID)), - childRecordsCheck( - TXN_WITH_NEGATIVE_SERIAL, - CONTRACT_REVERT_EXECUTED, - recordWith().status(INVALID_TOKEN_NFT_SERIAL_NUMBER)), - childRecordsCheck( - TXN_ACCOUNT_DOES_NOT_OWN_NFT, - CONTRACT_REVERT_EXECUTED, - recordWith().status(SPENDER_DOES_NOT_HAVE_ALLOWANCE))); + }), + childRecordsCheck( + TXN_WITH_INVALID_RECEIVER_ADDRESS, + CONTRACT_REVERT_EXECUTED, + recordWith().status(INVALID_ALIAS_KEY)), + childRecordsCheck( + TXN_WITH_INVALID_SENDER_ADDRESS, + CONTRACT_REVERT_EXECUTED, + recordWith().status(INVALID_ACCOUNT_ID)), + childRecordsCheck( + TXN_WITH_INVALID_TOKEN_ADDRESS, + CONTRACT_REVERT_EXECUTED, + recordWith().status(INVALID_TOKEN_ID)), + childRecordsCheck( + TXN_WITH_NEGATIVE_SERIAL, + CONTRACT_REVERT_EXECUTED, + recordWith().status(INVALID_TOKEN_NFT_SERIAL_NUMBER)), + childRecordsCheck( + TXN_ACCOUNT_DOES_NOT_OWN_NFT, + CONTRACT_REVERT_EXECUTED, + recordWith().status(SPENDER_DOES_NOT_HAVE_ALLOWANCE))); } } diff --git a/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/precompile/ContractMintHTSSuite.java b/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/precompile/ContractMintHTSSuite.java index 576acf344d44..558e3eed9fb9 100644 --- a/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/precompile/ContractMintHTSSuite.java +++ b/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/precompile/ContractMintHTSSuite.java @@ -18,7 +18,6 @@ import static com.hedera.services.bdd.junit.TestTags.SMART_CONTRACT; import static com.hedera.services.bdd.spec.HapiPropertySource.idAsHeadlongAddress; -import static com.hedera.services.bdd.spec.HapiSpec.defaultHapiSpec; import static com.hedera.services.bdd.spec.HapiSpec.hapiTest; import static com.hedera.services.bdd.spec.assertions.ContractFnResultAsserts.resultWith; import static com.hedera.services.bdd.spec.assertions.TransactionRecordAsserts.recordWith; @@ -109,29 +108,28 @@ final Stream mintTokensWithExtremeValues() { var invalidTokenNFTTest = "invalidTokenNFTTest"; var invalidTokenTest = "invalidTokenTest"; - return defaultHapiSpec("MintFungibleTokenWithInvalidAndExtremeValues") - .given( - newKeyNamed(MULTI_KEY), - cryptoCreate(ACCOUNT).balance(ONE_HUNDRED_HBARS), - cryptoCreate(RECIPIENT).maxAutomaticTokenAssociations(1), - cryptoCreate(TOKEN_TREASURY), - tokenCreate(NON_FUNGIBLE_TOKEN) - .tokenType(TokenType.NON_FUNGIBLE_UNIQUE) - .supplyType(TokenSupplyType.INFINITE) - .initialSupply(0) - .treasury(TOKEN_TREASURY) - .adminKey(MULTI_KEY) - .supplyKey(MULTI_KEY), - tokenCreate(FUNGIBLE_TOKEN) - .tokenType(TokenType.FUNGIBLE_COMMON) - .supplyType(TokenSupplyType.INFINITE) - .initialSupply(1000) - .treasury(TOKEN_TREASURY) - .adminKey(MULTI_KEY) - .supplyKey(MULTI_KEY), - uploadInitCode(NEGATIVE_MINT_CONTRACT), - contractCreate(NEGATIVE_MINT_CONTRACT).gas(GAS_TO_OFFER)) - .when(withOpContext((spec, opLog) -> allRunFor( + return hapiTest( + newKeyNamed(MULTI_KEY), + cryptoCreate(ACCOUNT).balance(ONE_HUNDRED_HBARS), + cryptoCreate(RECIPIENT).maxAutomaticTokenAssociations(1), + cryptoCreate(TOKEN_TREASURY), + tokenCreate(NON_FUNGIBLE_TOKEN) + .tokenType(TokenType.NON_FUNGIBLE_UNIQUE) + .supplyType(TokenSupplyType.INFINITE) + .initialSupply(0) + .treasury(TOKEN_TREASURY) + .adminKey(MULTI_KEY) + .supplyKey(MULTI_KEY), + tokenCreate(FUNGIBLE_TOKEN) + .tokenType(TokenType.FUNGIBLE_COMMON) + .supplyType(TokenSupplyType.INFINITE) + .initialSupply(1000) + .treasury(TOKEN_TREASURY) + .adminKey(MULTI_KEY) + .supplyKey(MULTI_KEY), + uploadInitCode(NEGATIVE_MINT_CONTRACT), + contractCreate(NEGATIVE_MINT_CONTRACT).gas(GAS_TO_OFFER), + withOpContext((spec, opLog) -> allRunFor( spec, // Fungible Mint calls with extreme values contractCall( @@ -202,14 +200,11 @@ final Stream mintTokensWithExtremeValues() { .alsoSigningWithFullPrefix(MULTI_KEY) .gas(GAS_TO_OFFER), getTxnRecord(invalidTokenTest).andAllChildRecords().logged(), - getTxnRecord(invalidTokenNFTTest).andAllChildRecords().logged()))) - .then( - getAccountBalance(TOKEN_TREASURY).hasTokenBalance(FUNGIBLE_TOKEN, 1_000), - getAccountBalance(TOKEN_TREASURY).hasTokenBalance(NON_FUNGIBLE_TOKEN, 0), - childRecordsCheck( - invalidTokenTest, SUCCESS, recordWith().status(INVALID_TOKEN_ID)), - childRecordsCheck( - invalidTokenNFTTest, SUCCESS, recordWith().status(INVALID_TOKEN_ID))); + getTxnRecord(invalidTokenNFTTest).andAllChildRecords().logged())), + getAccountBalance(TOKEN_TREASURY).hasTokenBalance(FUNGIBLE_TOKEN, 1_000), + getAccountBalance(TOKEN_TREASURY).hasTokenBalance(NON_FUNGIBLE_TOKEN, 0), + childRecordsCheck(invalidTokenTest, SUCCESS, recordWith().status(INVALID_TOKEN_ID)), + childRecordsCheck(invalidTokenNFTTest, SUCCESS, recordWith().status(INVALID_TOKEN_ID))); } @HapiTest @@ -220,29 +215,28 @@ final Stream mintTokensWithInvalidValues() { var mintWithZeroedAddressTest = "mintWithZeroedAddressTest"; var mintWithZeroedAddressAndMetadataTest = "mintWithZeroedAddressAndMetadataTest"; - return defaultHapiSpec("MintFungibleTokenWithInvalidAndExtremeValues") - .given( - newKeyNamed(MULTI_KEY), - cryptoCreate(ACCOUNT).balance(ONE_HUNDRED_HBARS), - cryptoCreate(RECIPIENT).maxAutomaticTokenAssociations(1), - cryptoCreate(TOKEN_TREASURY), - tokenCreate(FUNGIBLE_TOKEN) - .tokenType(TokenType.FUNGIBLE_COMMON) - .supplyType(TokenSupplyType.INFINITE) - .initialSupply(1000) - .treasury(TOKEN_TREASURY) - .adminKey(MULTI_KEY) - .supplyKey(MULTI_KEY), - tokenCreate(NON_FUNGIBLE_TOKEN) - .tokenType(TokenType.FUNGIBLE_COMMON) - .supplyType(TokenSupplyType.INFINITE) - .initialSupply(0) - .treasury(TOKEN_TREASURY) - .adminKey(MULTI_KEY) - .supplyKey(MULTI_KEY), - uploadInitCode(NEGATIVE_MINT_CONTRACT), - contractCreate(NEGATIVE_MINT_CONTRACT).gas(GAS_TO_OFFER)) - .when(withOpContext((spec, opLog) -> allRunFor( + return hapiTest( + newKeyNamed(MULTI_KEY), + cryptoCreate(ACCOUNT).balance(ONE_HUNDRED_HBARS), + cryptoCreate(RECIPIENT).maxAutomaticTokenAssociations(1), + cryptoCreate(TOKEN_TREASURY), + tokenCreate(FUNGIBLE_TOKEN) + .tokenType(TokenType.FUNGIBLE_COMMON) + .supplyType(TokenSupplyType.INFINITE) + .initialSupply(1000) + .treasury(TOKEN_TREASURY) + .adminKey(MULTI_KEY) + .supplyKey(MULTI_KEY), + tokenCreate(NON_FUNGIBLE_TOKEN) + .tokenType(TokenType.FUNGIBLE_COMMON) + .supplyType(TokenSupplyType.INFINITE) + .initialSupply(0) + .treasury(TOKEN_TREASURY) + .adminKey(MULTI_KEY) + .supplyKey(MULTI_KEY), + uploadInitCode(NEGATIVE_MINT_CONTRACT), + contractCreate(NEGATIVE_MINT_CONTRACT).gas(GAS_TO_OFFER), + withOpContext((spec, opLog) -> allRunFor( spec, newKeyNamed(CONTRACT_KEY).shape(CONTRACT.signedWith(NEGATIVE_MINT_CONTRACT)), tokenUpdate(FUNGIBLE_TOKEN).supplyKey(CONTRACT_KEY).signedByPayerAnd(MULTI_KEY), @@ -293,33 +287,31 @@ final Stream mintTokensWithInvalidValues() { .logged(), getTxnRecord(mintWithZeroedAddressAndMetadataTest) .andAllChildRecords() - .logged()))) - .then( - getAccountBalance(TOKEN_TREASURY).hasTokenBalance(FUNGIBLE_TOKEN, 1_000), - getAccountBalance(TOKEN_TREASURY).hasTokenBalance(NON_FUNGIBLE_TOKEN, 0), - childRecordsCheck( - fungibleMintWithMetadataTest, - CONTRACT_REVERT_EXECUTED, - recordWith().status(INVALID_TRANSACTION_BODY)), - childRecordsCheck( - mintWithZeroedAddressTest, - CONTRACT_REVERT_EXECUTED, - recordWith().status(INVALID_TOKEN_ID)), - childRecordsCheck( - mintWithZeroedAddressAndMetadataTest, - CONTRACT_REVERT_EXECUTED, - recordWith().status(INVALID_TOKEN_ID)), - withOpContext((spec, opLog) -> { - final var baseTxnId = spec.registry().getTxnId(mintWithZeroedAddressAndMetadataTest); - final var childTxnId = - baseTxnId.toBuilder().setNonce(1).build(); - allRunFor(spec, getReceipt(childTxnId).hasPriorityStatus(INVALID_TOKEN_ID)); - allRunFor( - spec, - getTxnRecord(childTxnId) - .assertingNothingAboutHashes() - .hasPriority(recordWith().status(INVALID_TOKEN_ID))); - })); + .logged())), + getAccountBalance(TOKEN_TREASURY).hasTokenBalance(FUNGIBLE_TOKEN, 1_000), + getAccountBalance(TOKEN_TREASURY).hasTokenBalance(NON_FUNGIBLE_TOKEN, 0), + childRecordsCheck( + fungibleMintWithMetadataTest, + CONTRACT_REVERT_EXECUTED, + recordWith().status(INVALID_TRANSACTION_BODY)), + childRecordsCheck( + mintWithZeroedAddressTest, + CONTRACT_REVERT_EXECUTED, + recordWith().status(INVALID_TOKEN_ID)), + childRecordsCheck( + mintWithZeroedAddressAndMetadataTest, + CONTRACT_REVERT_EXECUTED, + recordWith().status(INVALID_TOKEN_ID)), + withOpContext((spec, opLog) -> { + final var baseTxnId = spec.registry().getTxnId(mintWithZeroedAddressAndMetadataTest); + final var childTxnId = baseTxnId.toBuilder().setNonce(1).build(); + allRunFor(spec, getReceipt(childTxnId).hasPriorityStatus(INVALID_TOKEN_ID)); + allRunFor( + spec, + getTxnRecord(childTxnId) + .assertingNothingAboutHashes() + .hasPriority(recordWith().status(INVALID_TOKEN_ID))); + })); } @HapiTest diff --git a/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/precompile/ContractMintHTSV2SecurityModelSuite.java b/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/precompile/ContractMintHTSV2SecurityModelSuite.java index d6443b2595c7..2528a84842bc 100644 --- a/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/precompile/ContractMintHTSV2SecurityModelSuite.java +++ b/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/precompile/ContractMintHTSV2SecurityModelSuite.java @@ -18,7 +18,7 @@ import static com.hedera.services.bdd.junit.TestTags.SMART_CONTRACT; import static com.hedera.services.bdd.spec.HapiPropertySource.asToken; -import static com.hedera.services.bdd.spec.HapiSpec.defaultHapiSpec; +import static com.hedera.services.bdd.spec.HapiSpec.hapiTest; import static com.hedera.services.bdd.spec.assertions.TransactionRecordAsserts.recordWith; import static com.hedera.services.bdd.spec.keys.KeyShape.CONTRACT; import static com.hedera.services.bdd.spec.keys.KeyShape.ED25519; @@ -122,21 +122,20 @@ final Stream V2Security002FungibleTokenMintInTreasuryPositive() { final var amount = 10L; final AtomicReference fungible = new AtomicReference<>(); - return defaultHapiSpec("V2Security002FungibleTokenMintPositive") - .given( - cryptoCreate(TOKEN_TREASURY), - cryptoCreate(SIGNER2), - cryptoCreate(SIGNER).balance(ONE_MILLION_HBARS), - tokenCreate(FUNGIBLE_TOKEN) - .tokenType(TokenType.FUNGIBLE_COMMON) - .initialSupply(0) - .treasury(TOKEN_TREASURY) - .adminKey(TOKEN_TREASURY) - .supplyKey(TOKEN_TREASURY) - .exposingCreatedIdTo(idLit -> fungible.set(asToken(idLit))), - uploadInitCode(HTS_CALLS), - contractCreate(HTS_CALLS)) - .when(withOpContext((spec, opLog) -> allRunFor( + return hapiTest( + cryptoCreate(TOKEN_TREASURY), + cryptoCreate(SIGNER2), + cryptoCreate(SIGNER).balance(ONE_MILLION_HBARS), + tokenCreate(FUNGIBLE_TOKEN) + .tokenType(TokenType.FUNGIBLE_COMMON) + .initialSupply(0) + .treasury(TOKEN_TREASURY) + .adminKey(TOKEN_TREASURY) + .supplyKey(TOKEN_TREASURY) + .exposingCreatedIdTo(idLit -> fungible.set(asToken(idLit))), + uploadInitCode(HTS_CALLS), + contractCreate(HTS_CALLS), + withOpContext((spec, opLog) -> allRunFor( spec, // Create a key with shape contract and the contractId of HTSCalls contract newKeyNamed(CONTRACT_KEY).shape(CONTRACT.signedWith(HTS_CALLS)), @@ -231,21 +230,20 @@ final Stream V2Security002FungibleTokenMintInTreasuryPositive() { // Assert that the token is minted - total supply should be increased getTokenInfo(FUNGIBLE_TOKEN).hasTotalSupply(4 * amount), // Assert the token is mined in the token treasury account - getAccountBalance(TOKEN_TREASURY).hasTokenBalance(FUNGIBLE_TOKEN, 4 * amount)))) - .then( - // Verify that each test case has 1 successful child record - getTxnRecord(SIGNER_MINTS_WITH_CONTRACT_ID) - .andAllChildRecords() - .hasChildRecords(recordWith().status(SUCCESS)), - getTxnRecord(TREASURY_MINTS) - .andAllChildRecords() - .hasChildRecords(recordWith().status(SUCCESS)), - getTxnRecord(SIGNER_AND_PAYER_ARE_DIFFERENT) - .andAllChildRecords() - .hasChildRecords(recordWith().status(SUCCESS)), - getTxnRecord(SIGNER_MINTS_WITH_THRESHOLD_KEY) - .andAllChildRecords() - .hasChildRecords(recordWith().status(SUCCESS))); + getAccountBalance(TOKEN_TREASURY).hasTokenBalance(FUNGIBLE_TOKEN, 4 * amount))), + // Verify that each test case has 1 successful child record + getTxnRecord(SIGNER_MINTS_WITH_CONTRACT_ID) + .andAllChildRecords() + .hasChildRecords(recordWith().status(SUCCESS)), + getTxnRecord(TREASURY_MINTS) + .andAllChildRecords() + .hasChildRecords(recordWith().status(SUCCESS)), + getTxnRecord(SIGNER_AND_PAYER_ARE_DIFFERENT) + .andAllChildRecords() + .hasChildRecords(recordWith().status(SUCCESS)), + getTxnRecord(SIGNER_MINTS_WITH_THRESHOLD_KEY) + .andAllChildRecords() + .hasChildRecords(recordWith().status(SUCCESS))); } @HapiTest @@ -253,24 +251,23 @@ final Stream V2Security003NonFungibleTokenMintInTreasuryPositive() final var amount = 1; final AtomicReference nonFungible = new AtomicReference<>(); - return defaultHapiSpec("V2Security003NonFungibleTokenMintPositive") - .given( - cryptoCreate(TOKEN_TREASURY), - cryptoCreate(SIGNER2), - cryptoCreate(SIGNER).balance(ONE_MILLION_HBARS), - tokenCreate(NON_FUNGIBLE_TOKEN) - .tokenType(TokenType.NON_FUNGIBLE_UNIQUE) - .initialSupply(0) - .treasury(TOKEN_TREASURY) - .adminKey(TOKEN_TREASURY) - .supplyKey(TOKEN_TREASURY) - .exposingCreatedIdTo(idLit -> nonFungible.set(asToken(idLit))), - uploadInitCode(HTS_CALLS), - contractCreate(HTS_CALLS), - uploadInitCode(MINT_CONTRACT), - sourcing(() -> contractCreate( - MINT_CONTRACT, HapiParserUtil.asHeadlongAddress(asAddress(nonFungible.get()))))) - .when(withOpContext((spec, opLog) -> allRunFor( + return hapiTest( + cryptoCreate(TOKEN_TREASURY), + cryptoCreate(SIGNER2), + cryptoCreate(SIGNER).balance(ONE_MILLION_HBARS), + tokenCreate(NON_FUNGIBLE_TOKEN) + .tokenType(TokenType.NON_FUNGIBLE_UNIQUE) + .initialSupply(0) + .treasury(TOKEN_TREASURY) + .adminKey(TOKEN_TREASURY) + .supplyKey(TOKEN_TREASURY) + .exposingCreatedIdTo(idLit -> nonFungible.set(asToken(idLit))), + uploadInitCode(HTS_CALLS), + contractCreate(HTS_CALLS), + uploadInitCode(MINT_CONTRACT), + sourcing(() -> + contractCreate(MINT_CONTRACT, HapiParserUtil.asHeadlongAddress(asAddress(nonFungible.get())))), + withOpContext((spec, opLog) -> allRunFor( spec, // Create a key with shape contract and the contractId of HTSCalls contract newKeyNamed(CONTRACT_KEY).shape(CONTRACT.signedWith(HTS_CALLS)), @@ -367,21 +364,20 @@ final Stream V2Security003NonFungibleTokenMintInTreasuryPositive() // Assert that the token is minted - total supply should be increased getTokenInfo(NON_FUNGIBLE_TOKEN).hasTotalSupply(4 * amount), // Assert the token is mined in the token treasury account - getAccountBalance(TOKEN_TREASURY).hasTokenBalance(NON_FUNGIBLE_TOKEN, 4 * amount)))) - .then( - // Verify that each test case has 1 successful child record - getTxnRecord(SIGNER_MINTS_WITH_CONTRACT_ID) - .andAllChildRecords() - .hasChildRecords(recordWith().status(SUCCESS)), - getTxnRecord(TREASURY_MINTS) - .andAllChildRecords() - .hasChildRecords(recordWith().status(SUCCESS)), - getTxnRecord(SIGNER_AND_PAYER_ARE_DIFFERENT) - .andAllChildRecords() - .hasChildRecords(recordWith().status(SUCCESS)), - getTxnRecord(SIGNER_MINTS_WITH_THRESHOLD_KEY) - .andAllChildRecords() - .hasChildRecords(recordWith().status(SUCCESS))); + getAccountBalance(TOKEN_TREASURY).hasTokenBalance(NON_FUNGIBLE_TOKEN, 4 * amount))), + // Verify that each test case has 1 successful child record + getTxnRecord(SIGNER_MINTS_WITH_CONTRACT_ID) + .andAllChildRecords() + .hasChildRecords(recordWith().status(SUCCESS)), + getTxnRecord(TREASURY_MINTS) + .andAllChildRecords() + .hasChildRecords(recordWith().status(SUCCESS)), + getTxnRecord(SIGNER_AND_PAYER_ARE_DIFFERENT) + .andAllChildRecords() + .hasChildRecords(recordWith().status(SUCCESS)), + getTxnRecord(SIGNER_MINTS_WITH_THRESHOLD_KEY) + .andAllChildRecords() + .hasChildRecords(recordWith().status(SUCCESS))); } @HapiTest @@ -389,23 +385,22 @@ final Stream V2Security002FungibleTokenMintInTreasuryNegative() { final var amount = 10L; final AtomicReference fungible = new AtomicReference<>(); - return defaultHapiSpec("V2Security002FungibleTokenMintNegative") - .given( - cryptoCreate(TOKEN_TREASURY), - cryptoCreate(SIGNER).balance(ONE_MILLION_HBARS), - tokenCreate(FUNGIBLE_TOKEN) - .tokenType(TokenType.FUNGIBLE_COMMON) - .initialSupply(0) - .treasury(TOKEN_TREASURY) - .adminKey(TOKEN_TREASURY) - .supplyKey(TOKEN_TREASURY) - .exposingCreatedIdTo(idLit -> fungible.set(asToken(idLit))), - uploadInitCode(HTS_CALLS), - contractCreate(HTS_CALLS), - uploadInitCode(MINT_CONTRACT), - sourcing(() -> contractCreate( - MINT_CONTRACT, HapiParserUtil.asHeadlongAddress(asAddress(fungible.get()))))) - .when(withOpContext((spec, opLog) -> allRunFor( + return hapiTest( + cryptoCreate(TOKEN_TREASURY), + cryptoCreate(SIGNER).balance(ONE_MILLION_HBARS), + tokenCreate(FUNGIBLE_TOKEN) + .tokenType(TokenType.FUNGIBLE_COMMON) + .initialSupply(0) + .treasury(TOKEN_TREASURY) + .adminKey(TOKEN_TREASURY) + .supplyKey(TOKEN_TREASURY) + .exposingCreatedIdTo(idLit -> fungible.set(asToken(idLit))), + uploadInitCode(HTS_CALLS), + contractCreate(HTS_CALLS), + uploadInitCode(MINT_CONTRACT), + sourcing(() -> + contractCreate(MINT_CONTRACT, HapiParserUtil.asHeadlongAddress(asAddress(fungible.get())))), + withOpContext((spec, opLog) -> allRunFor( spec, // Test Case 1: Signer paying and signing a token mint transaction, when the token // is expected to be minted in the token treasury account @@ -485,41 +480,39 @@ final Stream V2Security002FungibleTokenMintInTreasuryNegative() { // Assert that the token is NOT minted - total supply should be 0 getTokenInfo(FUNGIBLE_TOKEN).hasTotalSupply(0L), // Assert the token is NOT mined in the token treasury account - getAccountBalance(TOKEN_TREASURY).hasTokenBalance(FUNGIBLE_TOKEN, 0L)))) - .then( - // Verify that each test case has 1 child record with the correct error message - getTxnRecord(SIGNER_AND_TOKEN_HAVE_NO_UPDATED_KEYS) - .andAllChildRecords() - .hasChildRecords(recordWith().status(INVALID_FULL_PREFIX_SIGNATURE_FOR_PRECOMPILE)), - getTxnRecord(SIGNER_MINTS_WITH_SIGNER_PUBLIC_KEY_AND_WRONG_CONTRACT_ID) - .andAllChildRecords() - .hasChildRecords(recordWith().status(INVALID_FULL_PREFIX_SIGNATURE_FOR_PRECOMPILE)), - getTxnRecord(TOKEN_HAS_NO_UPDATED_KEY) - .andAllChildRecords() - .hasChildRecords(recordWith().status(INVALID_FULL_PREFIX_SIGNATURE_FOR_PRECOMPILE))); + getAccountBalance(TOKEN_TREASURY).hasTokenBalance(FUNGIBLE_TOKEN, 0L))), + // Verify that each test case has 1 child record with the correct error message + getTxnRecord(SIGNER_AND_TOKEN_HAVE_NO_UPDATED_KEYS) + .andAllChildRecords() + .hasChildRecords(recordWith().status(INVALID_FULL_PREFIX_SIGNATURE_FOR_PRECOMPILE)), + getTxnRecord(SIGNER_MINTS_WITH_SIGNER_PUBLIC_KEY_AND_WRONG_CONTRACT_ID) + .andAllChildRecords() + .hasChildRecords(recordWith().status(INVALID_FULL_PREFIX_SIGNATURE_FOR_PRECOMPILE)), + getTxnRecord(TOKEN_HAS_NO_UPDATED_KEY) + .andAllChildRecords() + .hasChildRecords(recordWith().status(INVALID_FULL_PREFIX_SIGNATURE_FOR_PRECOMPILE))); } @HapiTest final Stream V2Security003NonFungibleTokenMintInTreasuryNegative() { final AtomicReference nonFungible = new AtomicReference<>(); - return defaultHapiSpec("V2Security003NonFungibleTokenMintNegative") - .given( - cryptoCreate(TOKEN_TREASURY), - cryptoCreate(SIGNER).balance(ONE_MILLION_HBARS), - tokenCreate(NON_FUNGIBLE_TOKEN) - .tokenType(TokenType.NON_FUNGIBLE_UNIQUE) - .initialSupply(0) - .treasury(TOKEN_TREASURY) - .adminKey(TOKEN_TREASURY) - .supplyKey(TOKEN_TREASURY) - .exposingCreatedIdTo(idLit -> nonFungible.set(asToken(idLit))), - uploadInitCode(HTS_CALLS), - contractCreate(HTS_CALLS), - uploadInitCode(MINT_CONTRACT), - sourcing(() -> contractCreate( - MINT_CONTRACT, HapiParserUtil.asHeadlongAddress(asAddress(nonFungible.get()))))) - .when(withOpContext((spec, opLog) -> allRunFor( + return hapiTest( + cryptoCreate(TOKEN_TREASURY), + cryptoCreate(SIGNER).balance(ONE_MILLION_HBARS), + tokenCreate(NON_FUNGIBLE_TOKEN) + .tokenType(TokenType.NON_FUNGIBLE_UNIQUE) + .initialSupply(0) + .treasury(TOKEN_TREASURY) + .adminKey(TOKEN_TREASURY) + .supplyKey(TOKEN_TREASURY) + .exposingCreatedIdTo(idLit -> nonFungible.set(asToken(idLit))), + uploadInitCode(HTS_CALLS), + contractCreate(HTS_CALLS), + uploadInitCode(MINT_CONTRACT), + sourcing(() -> + contractCreate(MINT_CONTRACT, HapiParserUtil.asHeadlongAddress(asAddress(nonFungible.get())))), + withOpContext((spec, opLog) -> allRunFor( spec, newKeyNamed(THRESHOLD_KEY).shape(TRESHOLD_KEY_SHAPE.signedWith(sigs(ON, HTS_CALLS))), // Test Case 1: Signer paying and signing a token mint transaction, when the token @@ -599,41 +592,39 @@ final Stream V2Security003NonFungibleTokenMintInTreasuryNegative() // Assert that the token is NOT minted - total supply should be 0 getTokenInfo(NON_FUNGIBLE_TOKEN).hasTotalSupply(0L), // Assert the token is NOT mined in the token treasury account - getAccountBalance(TOKEN_TREASURY).hasTokenBalance(NON_FUNGIBLE_TOKEN, 0L)))) - .then( - // Verify that each test case has 1 child record with the correct error message - getTxnRecord(SIGNER_AND_TOKEN_HAVE_NO_UPDATED_KEYS) - .andAllChildRecords() - .hasChildRecords(recordWith().status(INVALID_FULL_PREFIX_SIGNATURE_FOR_PRECOMPILE)), - getTxnRecord(SIGNER_MINTS_WITH_SIGNER_PUBLIC_KEY_AND_WRONG_CONTRACT_ID) - .andAllChildRecords() - .hasChildRecords(recordWith().status(INVALID_FULL_PREFIX_SIGNATURE_FOR_PRECOMPILE)), - getTxnRecord(TOKEN_HAS_NO_UPDATED_KEY) - .andAllChildRecords() - .hasChildRecords(recordWith().status(INVALID_FULL_PREFIX_SIGNATURE_FOR_PRECOMPILE))); + getAccountBalance(TOKEN_TREASURY).hasTokenBalance(NON_FUNGIBLE_TOKEN, 0L))), + // Verify that each test case has 1 child record with the correct error message + getTxnRecord(SIGNER_AND_TOKEN_HAVE_NO_UPDATED_KEYS) + .andAllChildRecords() + .hasChildRecords(recordWith().status(INVALID_FULL_PREFIX_SIGNATURE_FOR_PRECOMPILE)), + getTxnRecord(SIGNER_MINTS_WITH_SIGNER_PUBLIC_KEY_AND_WRONG_CONTRACT_ID) + .andAllChildRecords() + .hasChildRecords(recordWith().status(INVALID_FULL_PREFIX_SIGNATURE_FOR_PRECOMPILE)), + getTxnRecord(TOKEN_HAS_NO_UPDATED_KEY) + .andAllChildRecords() + .hasChildRecords(recordWith().status(INVALID_FULL_PREFIX_SIGNATURE_FOR_PRECOMPILE))); } @HapiTest final Stream V2Security035TokenWithDelegateContractKeyCanNotMintFromDelegatecall() { - return defaultHapiSpec("V2Security035TokenWithDelegateContractKeyCanNotMintFromDelegatecal") - .given( - cryptoCreate(TOKEN_TREASURY), - cryptoCreate(SIGNER).balance(ONE_MILLION_HBARS), - tokenCreate(FUNGIBLE_TOKEN) - .tokenType(TokenType.FUNGIBLE_COMMON) - .initialSupply(0) - .treasury(TOKEN_TREASURY) - .adminKey(TOKEN_TREASURY) - .supplyKey(TOKEN_TREASURY), - tokenCreate(NON_FUNGIBLE_TOKEN) - .tokenType(TokenType.NON_FUNGIBLE_UNIQUE) - .initialSupply(0) - .treasury(TOKEN_TREASURY) - .adminKey(TOKEN_TREASURY) - .supplyKey(TOKEN_TREASURY), - uploadInitCode(MINT_TOKEN_VIA_DELEGATE_CALL), - contractCreate(MINT_TOKEN_VIA_DELEGATE_CALL)) - .when(withOpContext((spec, opLog) -> allRunFor( + return hapiTest( + cryptoCreate(TOKEN_TREASURY), + cryptoCreate(SIGNER).balance(ONE_MILLION_HBARS), + tokenCreate(FUNGIBLE_TOKEN) + .tokenType(TokenType.FUNGIBLE_COMMON) + .initialSupply(0) + .treasury(TOKEN_TREASURY) + .adminKey(TOKEN_TREASURY) + .supplyKey(TOKEN_TREASURY), + tokenCreate(NON_FUNGIBLE_TOKEN) + .tokenType(TokenType.NON_FUNGIBLE_UNIQUE) + .initialSupply(0) + .treasury(TOKEN_TREASURY) + .adminKey(TOKEN_TREASURY) + .supplyKey(TOKEN_TREASURY), + uploadInitCode(MINT_TOKEN_VIA_DELEGATE_CALL), + contractCreate(MINT_TOKEN_VIA_DELEGATE_CALL), + withOpContext((spec, opLog) -> allRunFor( spec, newKeyNamed(CONTRACT_KEY).shape(CONTRACT.signedWith(MINT_TOKEN_VIA_DELEGATE_CALL)), tokenUpdate(FUNGIBLE_TOKEN).supplyKey(CONTRACT_KEY).signedByPayerAnd(TOKEN_TREASURY), @@ -741,8 +732,8 @@ final Stream V2Security035TokenWithDelegateContractKeyCanNotMintFro // Assert that the token is NOT minted - total supply should be 0 getTokenInfo(FUNGIBLE_TOKEN).hasTotalSupply(0), // Assert the token is NOT mined in the token treasury account - getAccountBalance(TOKEN_TREASURY).hasTokenBalance(FUNGIBLE_TOKEN, 0L)))) - .then(withOpContext((spec, opLog) -> { + getAccountBalance(TOKEN_TREASURY).hasTokenBalance(FUNGIBLE_TOKEN, 0L))), + withOpContext((spec, opLog) -> { allRunFor( spec, // Verify that each test case has 1 top level call with the correct status @@ -766,28 +757,27 @@ final Stream V2Security040TokenWithDelegateContractKeyCanNotMintFro final AtomicReference fungible = new AtomicReference<>(); final AtomicReference nonFungible = new AtomicReference<>(); - return defaultHapiSpec("V2Security040TokenWithDelegateContractKeyCanNotMintFromStaticcall") - .given( - cryptoCreate(TOKEN_TREASURY).balance(ONE_MILLION_HBARS), - cryptoCreate(SIGNER).balance(ONE_MILLION_HBARS), - tokenCreate(FUNGIBLE_TOKEN) - .tokenType(TokenType.FUNGIBLE_COMMON) - .initialSupply(0) - .treasury(TOKEN_TREASURY) - .adminKey(TOKEN_TREASURY) - .supplyKey(TOKEN_TREASURY) - .exposingCreatedIdTo(idLit -> fungible.set(asToken(idLit))), - tokenCreate(NON_FUNGIBLE_TOKEN) - .tokenType(TokenType.NON_FUNGIBLE_UNIQUE) - .initialSupply(0) - .treasury(TOKEN_TREASURY) - .adminKey(TOKEN_TREASURY) - .supplyKey(TOKEN_TREASURY) - .exposingCreatedIdTo(idLit -> nonFungible.set(asToken(idLit))), - uploadInitCode(MINT_TOKEN_VIA_STATIC_CALL, MINT_TOKEN_VIA_NESTED_STATIC_CALL, SERVICE_CONTRACT), - contractCreate(MINT_TOKEN_VIA_STATIC_CALL), - contractCreate(SERVICE_CONTRACT)) - .when(withOpContext((spec, opLog) -> allRunFor( + return hapiTest( + cryptoCreate(TOKEN_TREASURY).balance(ONE_MILLION_HBARS), + cryptoCreate(SIGNER).balance(ONE_MILLION_HBARS), + tokenCreate(FUNGIBLE_TOKEN) + .tokenType(TokenType.FUNGIBLE_COMMON) + .initialSupply(0) + .treasury(TOKEN_TREASURY) + .adminKey(TOKEN_TREASURY) + .supplyKey(TOKEN_TREASURY) + .exposingCreatedIdTo(idLit -> fungible.set(asToken(idLit))), + tokenCreate(NON_FUNGIBLE_TOKEN) + .tokenType(TokenType.NON_FUNGIBLE_UNIQUE) + .initialSupply(0) + .treasury(TOKEN_TREASURY) + .adminKey(TOKEN_TREASURY) + .supplyKey(TOKEN_TREASURY) + .exposingCreatedIdTo(idLit -> nonFungible.set(asToken(idLit))), + uploadInitCode(MINT_TOKEN_VIA_STATIC_CALL, MINT_TOKEN_VIA_NESTED_STATIC_CALL, SERVICE_CONTRACT), + contractCreate(MINT_TOKEN_VIA_STATIC_CALL), + contractCreate(SERVICE_CONTRACT), + withOpContext((spec, opLog) -> allRunFor( spec, contractCreate( MINT_TOKEN_VIA_NESTED_STATIC_CALL, @@ -836,12 +826,9 @@ final Stream V2Security040TokenWithDelegateContractKeyCanNotMintFro // Assert that the token is NOT minted - total supply should be 0 getTokenInfo(NON_FUNGIBLE_TOKEN).hasTotalSupply(0), // Assert the token is NOT mined in the token treasury account - getAccountBalance(TOKEN_TREASURY).hasTokenBalance(NON_FUNGIBLE_TOKEN, 0L)))) - .then( - emptyChildRecordsCheck( - STATIC_CALL_WHEN_FUNGIBLE_TOKEN_HAS_CONTRACT_ID, CONTRACT_REVERT_EXECUTED), - emptyChildRecordsCheck( - STATIC_CALL_WHEN_NON_FUNGIBLE_TOKEN_HAS_CONTRACT_ID, CONTRACT_REVERT_EXECUTED)); + getAccountBalance(TOKEN_TREASURY).hasTokenBalance(NON_FUNGIBLE_TOKEN, 0L))), + emptyChildRecordsCheck(STATIC_CALL_WHEN_FUNGIBLE_TOKEN_HAS_CONTRACT_ID, CONTRACT_REVERT_EXECUTED), + emptyChildRecordsCheck(STATIC_CALL_WHEN_NON_FUNGIBLE_TOKEN_HAS_CONTRACT_ID, CONTRACT_REVERT_EXECUTED)); } @HapiTest @@ -850,29 +837,28 @@ final Stream V2Security040TokenWithDelegateContractKeyCanNotMintFro final AtomicReference nonFungible = new AtomicReference<>(); final String precompileAddress = "0000000000000000000000000000000000000167"; - return defaultHapiSpec("V2Security040TokenWithDelegateContractKeyCanNotMintFromCallcode") - .given( - newKeyNamed(THRESHOLD_KEY), - cryptoCreate(TOKEN_TREASURY).key(THRESHOLD_KEY).balance(THOUSAND_HBAR), - cryptoCreate(RECEIVER), - cryptoCreate(SIGNER).balance(THOUSAND_HBAR), - tokenCreate(FUNGIBLE_TOKEN) - .tokenType(TokenType.FUNGIBLE_COMMON) - .initialSupply(0) - .treasury(TOKEN_TREASURY) - .adminKey(TOKEN_TREASURY) - .supplyKey(TOKEN_TREASURY) - .exposingCreatedIdTo(idLit -> fungible.set(asToken(idLit))), - tokenCreate(NON_FUNGIBLE_TOKEN) - .tokenType(TokenType.NON_FUNGIBLE_UNIQUE) - .initialSupply(0) - .treasury(TOKEN_TREASURY) - .adminKey(TOKEN_TREASURY) - .supplyKey(TOKEN_TREASURY) - .exposingCreatedIdTo(idLit -> nonFungible.set(asToken(idLit))), - uploadInitCode(MINT_TOKEN_VIA_CALLCODE), - contractCreate(MINT_TOKEN_VIA_CALLCODE)) - .when(withOpContext((spec, opLog) -> allRunFor( + return hapiTest( + newKeyNamed(THRESHOLD_KEY), + cryptoCreate(TOKEN_TREASURY).key(THRESHOLD_KEY).balance(THOUSAND_HBAR), + cryptoCreate(RECEIVER), + cryptoCreate(SIGNER).balance(THOUSAND_HBAR), + tokenCreate(FUNGIBLE_TOKEN) + .tokenType(TokenType.FUNGIBLE_COMMON) + .initialSupply(0) + .treasury(TOKEN_TREASURY) + .adminKey(TOKEN_TREASURY) + .supplyKey(TOKEN_TREASURY) + .exposingCreatedIdTo(idLit -> fungible.set(asToken(idLit))), + tokenCreate(NON_FUNGIBLE_TOKEN) + .tokenType(TokenType.NON_FUNGIBLE_UNIQUE) + .initialSupply(0) + .treasury(TOKEN_TREASURY) + .adminKey(TOKEN_TREASURY) + .supplyKey(TOKEN_TREASURY) + .exposingCreatedIdTo(idLit -> nonFungible.set(asToken(idLit))), + uploadInitCode(MINT_TOKEN_VIA_CALLCODE), + contractCreate(MINT_TOKEN_VIA_CALLCODE), + withOpContext((spec, opLog) -> allRunFor( spec, newKeyNamed(CONTRACT_KEY) .shape(TRESHOLD_KEY_SHAPE.signedWith(sigs(ON, MINT_TOKEN_VIA_CALLCODE))), @@ -887,8 +873,10 @@ final Stream V2Security040TokenWithDelegateContractKeyCanNotMintFro asHeadlongAddress(precompileAddress), Bytes.wrap(MintTranslator.MINT_V2 .encodeCallWithArgs( - asHeadlongAddress(asAddress(spec.registry() - .getTokenID(FUNGIBLE_TOKEN))), + asHeadlongAddress( + asAddress( + spec.registry() + .getTokenID(FUNGIBLE_TOKEN))), 1L, EMPTY_METADATA) .array()) @@ -917,8 +905,11 @@ final Stream V2Security040TokenWithDelegateContractKeyCanNotMintFro asHeadlongAddress("0000000000000000000000000000000000000167"), Bytes.wrap(MintTranslator.MINT_V2 .encodeCallWithArgs( - asHeadlongAddress(asAddress(spec.registry() - .getTokenID(NON_FUNGIBLE_TOKEN))), + asHeadlongAddress( + asAddress( + spec.registry() + .getTokenID( + NON_FUNGIBLE_TOKEN))), 1L, TEST_METADATA_2) .array()) @@ -934,9 +925,8 @@ final Stream V2Security040TokenWithDelegateContractKeyCanNotMintFro // Assert that the token is NOT minted - total supply should be 0 getTokenInfo(NON_FUNGIBLE_TOKEN).hasTotalSupply(0), // Assert the token is NOT mined in the token treasury account - getAccountBalance(TOKEN_TREASURY).hasTokenBalance(NON_FUNGIBLE_TOKEN, 0L)))) - .then( - childRecordsCheck(CALLCODE_WHEN_FUNGIBLE_TOKEN_HAS_CONTRACT_ID, CONTRACT_REVERT_EXECUTED), - childRecordsCheck(CALLCODE_WHEN_NON_FUNGIBLE_TOKEN_HAS_CONTRACT_ID, CONTRACT_REVERT_EXECUTED)); + getAccountBalance(TOKEN_TREASURY).hasTokenBalance(NON_FUNGIBLE_TOKEN, 0L))), + childRecordsCheck(CALLCODE_WHEN_FUNGIBLE_TOKEN_HAS_CONTRACT_ID, CONTRACT_REVERT_EXECUTED), + childRecordsCheck(CALLCODE_WHEN_NON_FUNGIBLE_TOKEN_HAS_CONTRACT_ID, CONTRACT_REVERT_EXECUTED)); } } diff --git a/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/precompile/CreatePrecompileSuite.java b/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/precompile/CreatePrecompileSuite.java index 9f5a3a632ccb..0d0956a0de08 100644 --- a/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/precompile/CreatePrecompileSuite.java +++ b/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/precompile/CreatePrecompileSuite.java @@ -18,7 +18,6 @@ import static com.hedera.services.bdd.junit.TestTags.SMART_CONTRACT; import static com.hedera.services.bdd.spec.HapiPropertySource.asTokenString; -import static com.hedera.services.bdd.spec.HapiSpec.defaultHapiSpec; import static com.hedera.services.bdd.spec.HapiSpec.hapiTest; import static com.hedera.services.bdd.spec.assertions.AccountInfoAsserts.changeFromSnapshot; import static com.hedera.services.bdd.spec.keys.KeyShape.CONTRACT; @@ -129,27 +128,26 @@ final Stream fungibleTokenCreateHappyPath() { final var tokenCreateContractAsKeyDelegate = "tokenCreateContractAsKeyDelegate"; final var createTokenNum = new AtomicLong(); final AtomicReference ed2551Key = new AtomicReference<>(); - return defaultHapiSpec("fungibleTokenCreateHappyPath") - .given( - newKeyNamed(ECDSA_KEY).shape(SECP256K1), - newKeyNamed(CONTRACT_ADMIN_KEY), - cryptoCreate(ACCOUNT_TO_ASSOCIATE), - uploadInitCode(TOKEN_CREATE_CONTRACT), - cryptoCreate(ACCOUNT).balance(ONE_MILLION_HBARS), - contractCreate(TOKEN_CREATE_CONTRACT) - .autoRenewAccountId(ACCOUNT) - .adminKey(CONTRACT_ADMIN_KEY) - .gas(GAS_TO_OFFER), - newKeyNamed(THRESHOLD_KEY) - .shape(THRESHOLD_KEY_SHAPE.signedWith(sigs(ED25519_ON, TOKEN_CREATE_CONTRACT))) - .exposingKeyTo(k -> ed2551Key.set(k.getThresholdKey() - .getKeys() - .getKeys(0) - .getEd25519() - .toByteArray())), - cryptoUpdate(ACCOUNT).key(THRESHOLD_KEY), - cryptoUpdate(ACCOUNT_TO_ASSOCIATE).key(THRESHOLD_KEY)) - .when(withOpContext((spec, opLog) -> { + return hapiTest( + newKeyNamed(ECDSA_KEY).shape(SECP256K1), + newKeyNamed(CONTRACT_ADMIN_KEY), + cryptoCreate(ACCOUNT_TO_ASSOCIATE), + uploadInitCode(TOKEN_CREATE_CONTRACT), + cryptoCreate(ACCOUNT).balance(ONE_MILLION_HBARS), + contractCreate(TOKEN_CREATE_CONTRACT) + .autoRenewAccountId(ACCOUNT) + .adminKey(CONTRACT_ADMIN_KEY) + .gas(GAS_TO_OFFER), + newKeyNamed(THRESHOLD_KEY) + .shape(THRESHOLD_KEY_SHAPE.signedWith(sigs(ED25519_ON, TOKEN_CREATE_CONTRACT))) + .exposingKeyTo(k -> ed2551Key.set(k.getThresholdKey() + .getKeys() + .getKeys(0) + .getEd25519() + .toByteArray())), + cryptoUpdate(ACCOUNT).key(THRESHOLD_KEY), + cryptoUpdate(ACCOUNT_TO_ASSOCIATE).key(THRESHOLD_KEY), + withOpContext((spec, opLog) -> { spec.registry() .saveKey( ED25519KEY, @@ -194,8 +192,8 @@ final Stream fungibleTokenCreateHappyPath() { newKeyNamed(TOKEN_CREATE_CONTRACT_AS_KEY).shape(CONTRACT.signedWith(TOKEN_CREATE_CONTRACT)), newKeyNamed(tokenCreateContractAsKeyDelegate) .shape(DELEGATE_CONTRACT.signedWith(TOKEN_CREATE_CONTRACT))); - })) - .then(withOpContext((spec, opLog) -> allRunFor( + }), + withOpContext((spec, opLog) -> allRunFor( spec, getContractInfo(TOKEN_CREATE_CONTRACT) .has(ContractInfoAsserts.contractWith().autoRenewAccountId(ACCOUNT)) @@ -245,28 +243,27 @@ final Stream fungibleTokenCreateHappyPath() { final Stream inheritsSenderAutoRenewAccountIfAnyForNftCreate() { final var createdNftTokenNum = new AtomicLong(); final AtomicReference ed2551Key = new AtomicReference<>(); - return defaultHapiSpec("inheritsSenderAutoRenewAccountIfAnyForNftCreate") - .given( - newKeyNamed(ED25519KEY).shape(ED25519), - cryptoCreate(ACCOUNT).balance(ONE_MILLION_HBARS), - uploadInitCode(TOKEN_CREATE_CONTRACT), - contractCreate(TOKEN_CREATE_CONTRACT) - .autoRenewAccountId(ACCOUNT) - .gas(GAS_TO_OFFER), - newKeyNamed(THRESHOLD_KEY) - .shape(THRESHOLD_KEY_SHAPE.signedWith(sigs(ED25519_ON, TOKEN_CREATE_CONTRACT))) - .exposingKeyTo(k -> ed2551Key.set(k.getThresholdKey() - .getKeys() - .getKeys(0) - .getEd25519() - .toByteArray())), - cryptoUpdate(ACCOUNT).key(THRESHOLD_KEY)) - .when(withOpContext((spec, opLog) -> allRunFor( + return hapiTest( + newKeyNamed(ED25519KEY).shape(ED25519), + cryptoCreate(ACCOUNT).balance(ONE_MILLION_HBARS), + uploadInitCode(TOKEN_CREATE_CONTRACT), + contractCreate(TOKEN_CREATE_CONTRACT) + .autoRenewAccountId(ACCOUNT) + .gas(GAS_TO_OFFER), + newKeyNamed(THRESHOLD_KEY) + .shape(THRESHOLD_KEY_SHAPE.signedWith(sigs(ED25519_ON, TOKEN_CREATE_CONTRACT))) + .exposingKeyTo(k -> ed2551Key.set(k.getThresholdKey() + .getKeys() + .getKeys(0) + .getEd25519() + .toByteArray())), + cryptoUpdate(ACCOUNT).key(THRESHOLD_KEY), + withOpContext((spec, opLog) -> allRunFor( spec, getContractInfo(TOKEN_CREATE_CONTRACT) .has(ContractInfoAsserts.contractWith().autoRenewAccountId(ACCOUNT)) - .logged()))) - .then(withOpContext((spec, ignore) -> { + .logged())), + withOpContext((spec, ignore) -> { final var subop1 = balanceSnapshot(ACCOUNT_BALANCE, ACCOUNT); final var subop2 = contractCall( TOKEN_CREATE_CONTRACT, @@ -313,31 +310,30 @@ final Stream inheritsSenderAutoRenewAccountIfAnyForNftCreate() { final Stream inheritsSenderAutoRenewAccountForTokenCreate() { final var createTokenNum = new AtomicLong(); final AtomicReference ed2551Key = new AtomicReference<>(); - return defaultHapiSpec("inheritsSenderAutoRenewAccountForTokenCreate") - .given( - newKeyNamed(ECDSA_KEY).shape(SECP256K1), - newKeyNamed(ACCOUNT_TO_ASSOCIATE_KEY), - newKeyNamed(CONTRACT_ADMIN_KEY), - cryptoCreate(ACCOUNT).balance(ONE_MILLION_HBARS), - cryptoCreate(ACCOUNT_TO_ASSOCIATE).key(ACCOUNT_TO_ASSOCIATE_KEY), - uploadInitCode(TOKEN_CREATE_CONTRACT), - contractCreate(TOKEN_CREATE_CONTRACT) - .gas(GAS_TO_OFFER) - .adminKey(CONTRACT_ADMIN_KEY) - .autoRenewAccountId(ACCOUNT), - newKeyNamed(THRESHOLD_KEY) - .shape(THRESHOLD_KEY_SHAPE.signedWith(sigs(ED25519_ON, TOKEN_CREATE_CONTRACT))) - .exposingKeyTo(k -> ed2551Key.set(k.getThresholdKey() - .getKeys() - .getKeys(0) - .getEd25519() - .toByteArray())), - cryptoUpdate(ACCOUNT).key(THRESHOLD_KEY), - cryptoUpdate(ACCOUNT_TO_ASSOCIATE).key(THRESHOLD_KEY), - getContractInfo(TOKEN_CREATE_CONTRACT) - .has(ContractInfoAsserts.contractWith().autoRenewAccountId(ACCOUNT)) - .logged()) - .when(withOpContext((spec, opLog) -> allRunFor( + return hapiTest( + newKeyNamed(ECDSA_KEY).shape(SECP256K1), + newKeyNamed(ACCOUNT_TO_ASSOCIATE_KEY), + newKeyNamed(CONTRACT_ADMIN_KEY), + cryptoCreate(ACCOUNT).balance(ONE_MILLION_HBARS), + cryptoCreate(ACCOUNT_TO_ASSOCIATE).key(ACCOUNT_TO_ASSOCIATE_KEY), + uploadInitCode(TOKEN_CREATE_CONTRACT), + contractCreate(TOKEN_CREATE_CONTRACT) + .gas(GAS_TO_OFFER) + .adminKey(CONTRACT_ADMIN_KEY) + .autoRenewAccountId(ACCOUNT), + newKeyNamed(THRESHOLD_KEY) + .shape(THRESHOLD_KEY_SHAPE.signedWith(sigs(ED25519_ON, TOKEN_CREATE_CONTRACT))) + .exposingKeyTo(k -> ed2551Key.set(k.getThresholdKey() + .getKeys() + .getKeys(0) + .getEd25519() + .toByteArray())), + cryptoUpdate(ACCOUNT).key(THRESHOLD_KEY), + cryptoUpdate(ACCOUNT_TO_ASSOCIATE).key(THRESHOLD_KEY), + getContractInfo(TOKEN_CREATE_CONTRACT) + .has(ContractInfoAsserts.contractWith().autoRenewAccountId(ACCOUNT)) + .logged(), + withOpContext((spec, opLog) -> allRunFor( spec, contractCall( TOKEN_CREATE_CONTRACT, @@ -369,8 +365,8 @@ final Stream inheritsSenderAutoRenewAccountForTokenCreate() { final var res = (Address) result[0]; createTokenNum.set(res.value().longValueExact()); }) - .hasKnownStatus(SUCCESS)))) - .then(sourcing(() -> getTokenInfo(asTokenString(TokenID.newBuilder() + .hasKnownStatus(SUCCESS))), + sourcing(() -> getTokenInfo(asTokenString(TokenID.newBuilder() .setTokenNum(createTokenNum.get()) .build())) .logged() @@ -382,15 +378,14 @@ final Stream inheritsSenderAutoRenewAccountForTokenCreate() { @HapiTest final Stream nonFungibleTokenCreateHappyPath() { final var createdTokenNum = new AtomicLong(); - return defaultHapiSpec("nonFungibleTokenCreateHappyPath") - .given( - newKeyNamed(ED25519KEY).shape(ED25519), - cryptoCreate(ACCOUNT).balance(ONE_MILLION_HBARS).key(ED25519KEY), - uploadInitCode(TOKEN_CREATE_CONTRACT), - getAccountInfo(DEFAULT_CONTRACT_SENDER).savingSnapshot(DEFAULT_CONTRACT_SENDER)) - .when(withOpContext((spec, opLog) -> - allRunFor(spec, contractCreate(TOKEN_CREATE_CONTRACT).gas(GAS_TO_OFFER)))) - .then(withOpContext((spec, ignore) -> { + return hapiTest( + newKeyNamed(ED25519KEY).shape(ED25519), + cryptoCreate(ACCOUNT).balance(ONE_MILLION_HBARS).key(ED25519KEY), + uploadInitCode(TOKEN_CREATE_CONTRACT), + getAccountInfo(DEFAULT_CONTRACT_SENDER).savingSnapshot(DEFAULT_CONTRACT_SENDER), + withOpContext((spec, opLog) -> + allRunFor(spec, contractCreate(TOKEN_CREATE_CONTRACT).gas(GAS_TO_OFFER))), + withOpContext((spec, ignore) -> { final var subop1 = balanceSnapshot(ACCOUNT_BALANCE, ACCOUNT); final var subop2 = contractCall( TOKEN_CREATE_CONTRACT, @@ -474,23 +469,22 @@ final Stream nonFungibleTokenCreateHappyPath() { final Stream fungibleTokenCreateThenQueryAndTransfer() { final var createdTokenNum = new AtomicLong(); final AtomicReference ed2551Key = new AtomicReference<>(); - return defaultHapiSpec("fungibleTokenCreateThenQueryAndTransfer") - .given( - uploadInitCode(TOKEN_CREATE_CONTRACT), - contractCreate(TOKEN_CREATE_CONTRACT).gas(GAS_TO_OFFER), - newKeyNamed(TOKEN_CREATE_CONTRACT_AS_KEY).shape(CONTRACT.signedWith(TOKEN_CREATE_CONTRACT)), - newKeyNamed(THRESHOLD_KEY) - .shape(THRESHOLD_KEY_SHAPE.signedWith(sigs(ED25519_ON, TOKEN_CREATE_CONTRACT))) - .exposingKeyTo(k -> ed2551Key.set(k.getThresholdKey() - .getKeys() - .getKeys(0) - .getEd25519() - .toByteArray())), - cryptoCreate(ACCOUNT) - .balance(ONE_MILLION_HBARS) - .key(THRESHOLD_KEY) - .maxAutomaticTokenAssociations(1)) - .when(withOpContext((spec, opLog) -> { + return hapiTest( + uploadInitCode(TOKEN_CREATE_CONTRACT), + contractCreate(TOKEN_CREATE_CONTRACT).gas(GAS_TO_OFFER), + newKeyNamed(TOKEN_CREATE_CONTRACT_AS_KEY).shape(CONTRACT.signedWith(TOKEN_CREATE_CONTRACT)), + newKeyNamed(THRESHOLD_KEY) + .shape(THRESHOLD_KEY_SHAPE.signedWith(sigs(ED25519_ON, TOKEN_CREATE_CONTRACT))) + .exposingKeyTo(k -> ed2551Key.set(k.getThresholdKey() + .getKeys() + .getKeys(0) + .getEd25519() + .toByteArray())), + cryptoCreate(ACCOUNT) + .balance(ONE_MILLION_HBARS) + .key(THRESHOLD_KEY) + .maxAutomaticTokenAssociations(1), + withOpContext((spec, opLog) -> { spec.registry() .saveKey( ADMIN_KEY, @@ -519,8 +513,8 @@ final Stream fungibleTokenCreateThenQueryAndTransfer() { createdTokenNum.set(res.value().longValueExact()); }) .hasKnownStatus(SUCCESS)); - })) - .then(withOpContext((spec, opLog) -> allRunFor( + }), + withOpContext((spec, opLog) -> allRunFor( spec, getTxnRecord(FIRST_CREATE_TXN).andAllChildRecords().logged(), getAccountBalance(ACCOUNT).logged(), @@ -570,17 +564,15 @@ final Stream fungibleTokenCreateThenQueryAndTransfer() { @HapiTest final Stream nonFungibleTokenCreateThenQuery() { final var createdTokenNum = new AtomicLong(); - return defaultHapiSpec("nonFungibleTokenCreateThenQuery") - .given( - cryptoCreate(ACCOUNT).balance(ONE_MILLION_HBARS), - uploadInitCode(TOKEN_CREATE_CONTRACT), - contractCreate(TOKEN_CREATE_CONTRACT) - .autoRenewAccountId(ACCOUNT) - .gas(GAS_TO_OFFER), - newKeyNamed(THRESHOLD_KEY) - .shape(THRESHOLD_KEY_SHAPE.signedWith(sigs(ON, TOKEN_CREATE_CONTRACT))), - cryptoUpdate(ACCOUNT).key(THRESHOLD_KEY)) - .when(withOpContext((spec, opLog) -> allRunFor( + return hapiTest( + cryptoCreate(ACCOUNT).balance(ONE_MILLION_HBARS), + uploadInitCode(TOKEN_CREATE_CONTRACT), + contractCreate(TOKEN_CREATE_CONTRACT) + .autoRenewAccountId(ACCOUNT) + .gas(GAS_TO_OFFER), + newKeyNamed(THRESHOLD_KEY).shape(THRESHOLD_KEY_SHAPE.signedWith(sigs(ON, TOKEN_CREATE_CONTRACT))), + cryptoUpdate(ACCOUNT).key(THRESHOLD_KEY), + withOpContext((spec, opLog) -> allRunFor( spec, contractCall( TOKEN_CREATE_CONTRACT, @@ -601,56 +593,54 @@ final Stream nonFungibleTokenCreateThenQuery() { final var res = (Address) result[0]; createdTokenNum.set(res.value().longValueExact()); }), - newKeyNamed(TOKEN_CREATE_CONTRACT_AS_KEY).shape(CONTRACT.signedWith(TOKEN_CREATE_CONTRACT))))) - .then( - getTxnRecord(FIRST_CREATE_TXN).andAllChildRecords().logged(), - getAccountBalance(ACCOUNT).logged(), - getAccountBalance(TOKEN_CREATE_CONTRACT).logged(), - getContractInfo(TOKEN_CREATE_CONTRACT).logged(), - childRecordsCheck( - FIRST_CREATE_TXN, - ResponseCodeEnum.SUCCESS, - TransactionRecordAsserts.recordWith().status(SUCCESS), - TransactionRecordAsserts.recordWith().status(SUCCESS), - TransactionRecordAsserts.recordWith().status(SUCCESS)), - sourcing(() -> getAccountBalance(TOKEN_CREATE_CONTRACT) - .hasTokenBalance( - asTokenString(TokenID.newBuilder() - .setTokenNum(createdTokenNum.get()) - .build()), - 0)), - sourcing(() -> getTokenInfo(asTokenString(TokenID.newBuilder() + newKeyNamed(TOKEN_CREATE_CONTRACT_AS_KEY).shape(CONTRACT.signedWith(TOKEN_CREATE_CONTRACT)))), + getTxnRecord(FIRST_CREATE_TXN).andAllChildRecords().logged(), + getAccountBalance(ACCOUNT).logged(), + getAccountBalance(TOKEN_CREATE_CONTRACT).logged(), + getContractInfo(TOKEN_CREATE_CONTRACT).logged(), + childRecordsCheck( + FIRST_CREATE_TXN, + ResponseCodeEnum.SUCCESS, + TransactionRecordAsserts.recordWith().status(SUCCESS), + TransactionRecordAsserts.recordWith().status(SUCCESS), + TransactionRecordAsserts.recordWith().status(SUCCESS)), + sourcing(() -> getAccountBalance(TOKEN_CREATE_CONTRACT) + .hasTokenBalance( + asTokenString(TokenID.newBuilder() .setTokenNum(createdTokenNum.get()) - .build())) - .hasTokenType(TokenType.NON_FUNGIBLE_UNIQUE) - .hasSymbol(TOKEN_SYMBOL) - .hasName(TOKEN_NAME) - .hasDecimals(0) - .hasTotalSupply(0) - .hasEntityMemo(MEMO) - .hasTreasury(TOKEN_CREATE_CONTRACT) - .hasAutoRenewAccount(ACCOUNT) - .hasAutoRenewPeriod(AUTO_RENEW_PERIOD) - .hasSupplyType(TokenSupplyType.INFINITE) - .searchKeysGlobally() - .hasAdminKey(TOKEN_CREATE_CONTRACT_AS_KEY) - .hasSupplyKey(TOKEN_CREATE_CONTRACT_AS_KEY) - .hasPauseStatus(TokenPauseStatus.PauseNotApplicable) - .logged())); + .build()), + 0)), + sourcing(() -> getTokenInfo(asTokenString(TokenID.newBuilder() + .setTokenNum(createdTokenNum.get()) + .build())) + .hasTokenType(TokenType.NON_FUNGIBLE_UNIQUE) + .hasSymbol(TOKEN_SYMBOL) + .hasName(TOKEN_NAME) + .hasDecimals(0) + .hasTotalSupply(0) + .hasEntityMemo(MEMO) + .hasTreasury(TOKEN_CREATE_CONTRACT) + .hasAutoRenewAccount(ACCOUNT) + .hasAutoRenewPeriod(AUTO_RENEW_PERIOD) + .hasSupplyType(TokenSupplyType.INFINITE) + .searchKeysGlobally() + .hasAdminKey(TOKEN_CREATE_CONTRACT_AS_KEY) + .hasSupplyKey(TOKEN_CREATE_CONTRACT_AS_KEY) + .hasPauseStatus(TokenPauseStatus.PauseNotApplicable) + .logged())); } @HapiTest final Stream createTokenWithDefaultExpiryAndEmptyKeys() { final var tokenCreateContractAsKeyDelegate = "createTokenWithDefaultExpiryAndEmptyKeys"; final var createdTokenNum = new AtomicLong(); - return defaultHapiSpec("createTokenWithDefaultExpiryAndEmptyKeys") - .given( - uploadInitCode(TOKEN_CREATE_CONTRACT), - contractCreate(TOKEN_CREATE_CONTRACT).gas(GAS_TO_OFFER), - newKeyNamed(THRESHOLD_KEY) - .shape(THRESHOLD_KEY_SHAPE.signedWith(sigs(ED25519_ON, TOKEN_CREATE_CONTRACT))), - cryptoCreate(ACCOUNT).balance(ONE_MILLION_HBARS).key(THRESHOLD_KEY)) - .when(withOpContext((spec, opLog) -> allRunFor( + return hapiTest( + uploadInitCode(TOKEN_CREATE_CONTRACT), + contractCreate(TOKEN_CREATE_CONTRACT).gas(GAS_TO_OFFER), + newKeyNamed(THRESHOLD_KEY) + .shape(THRESHOLD_KEY_SHAPE.signedWith(sigs(ED25519_ON, TOKEN_CREATE_CONTRACT))), + cryptoCreate(ACCOUNT).balance(ONE_MILLION_HBARS).key(THRESHOLD_KEY), + withOpContext((spec, opLog) -> allRunFor( spec, contractCall(TOKEN_CREATE_CONTRACT, tokenCreateContractAsKeyDelegate) .via(FIRST_CREATE_TXN) @@ -662,33 +652,32 @@ final Stream createTokenWithDefaultExpiryAndEmptyKeys() { final var res = (Address) result[0]; createdTokenNum.set(res.value().longValueExact()); }) - .hasKnownStatus(SUCCESS)))) - .then( - getTxnRecord(FIRST_CREATE_TXN).andAllChildRecords().logged(), - getAccountBalance(ACCOUNT).logged(), - getAccountBalance(TOKEN_CREATE_CONTRACT).logged(), - getContractInfo(TOKEN_CREATE_CONTRACT).logged(), - childRecordsCheck( - FIRST_CREATE_TXN, - ResponseCodeEnum.SUCCESS, - TransactionRecordAsserts.recordWith().status(SUCCESS)), - sourcing(() -> getAccountBalance(TOKEN_CREATE_CONTRACT) - .hasTokenBalance( - asTokenString(TokenID.newBuilder() - .setTokenNum(createdTokenNum.get()) - .build()), - 200)), - sourcing(() -> getTokenInfo(asTokenString(TokenID.newBuilder() + .hasKnownStatus(SUCCESS))), + getTxnRecord(FIRST_CREATE_TXN).andAllChildRecords().logged(), + getAccountBalance(ACCOUNT).logged(), + getAccountBalance(TOKEN_CREATE_CONTRACT).logged(), + getContractInfo(TOKEN_CREATE_CONTRACT).logged(), + childRecordsCheck( + FIRST_CREATE_TXN, + ResponseCodeEnum.SUCCESS, + TransactionRecordAsserts.recordWith().status(SUCCESS)), + sourcing(() -> getAccountBalance(TOKEN_CREATE_CONTRACT) + .hasTokenBalance( + asTokenString(TokenID.newBuilder() .setTokenNum(createdTokenNum.get()) - .build())) - .hasTokenType(TokenType.FUNGIBLE_COMMON) - .hasDecimals(8) - .hasTotalSupply(200) - .hasTreasury(TOKEN_CREATE_CONTRACT) - .hasAutoRenewPeriod(0L) - .searchKeysGlobally() - .hasPauseStatus(TokenPauseStatus.PauseNotApplicable) - .logged())); + .build()), + 200)), + sourcing(() -> getTokenInfo(asTokenString(TokenID.newBuilder() + .setTokenNum(createdTokenNum.get()) + .build())) + .hasTokenType(TokenType.FUNGIBLE_COMMON) + .hasDecimals(8) + .hasTotalSupply(200) + .hasTreasury(TOKEN_CREATE_CONTRACT) + .hasAutoRenewPeriod(0L) + .searchKeysGlobally() + .hasPauseStatus(TokenPauseStatus.PauseNotApplicable) + .logged())); } // TEST-007 & TEST-016 @@ -1009,28 +998,27 @@ final Stream createTokenWithFixedFeeThenTransferAndAssessFee() { final var FEE_COLLECTOR = "feeCollector"; final var RECIPIENT = "recipient"; final var SECOND_RECIPIENT = "secondRecipient"; - return defaultHapiSpec("createTokenWithFixedFeeThenTransferAndAssessFee") - .given( - cryptoCreate(ACCOUNT).balance(ONE_MILLION_HBARS), - cryptoCreate(RECIPIENT).balance(ONE_HUNDRED_HBARS), - cryptoCreate(SECOND_RECIPIENT), - cryptoCreate(FEE_COLLECTOR).balance(0L), - uploadInitCode(TOKEN_MISC_OPERATIONS_CONTRACT), - contractCreate(TOKEN_MISC_OPERATIONS_CONTRACT) - .gas(GAS_TO_OFFER_2) - .autoRenewAccountId(ACCOUNT), - newKeyNamed(THRESHOLD_KEY) - .shape(THRESHOLD_KEY_SHAPE.signedWith(sigs(ON, TOKEN_MISC_OPERATIONS_CONTRACT))), - cryptoUpdate(ACCOUNT).key(THRESHOLD_KEY), - cryptoUpdate(FEE_COLLECTOR).key(THRESHOLD_KEY), - cryptoUpdate(RECIPIENT).key(THRESHOLD_KEY), - cryptoUpdate(SECOND_RECIPIENT).key(THRESHOLD_KEY), - cryptoTransfer(TokenMovement.movingHbar(ONE_HUNDRED_HBARS) - .between(GENESIS, TOKEN_MISC_OPERATIONS_CONTRACT)), - getContractInfo(TOKEN_MISC_OPERATIONS_CONTRACT) - .has(ContractInfoAsserts.contractWith().autoRenewAccountId(ACCOUNT)) - .logged()) - .when(withOpContext((spec, opLog) -> allRunFor( + return hapiTest( + cryptoCreate(ACCOUNT).balance(ONE_MILLION_HBARS), + cryptoCreate(RECIPIENT).balance(ONE_HUNDRED_HBARS), + cryptoCreate(SECOND_RECIPIENT), + cryptoCreate(FEE_COLLECTOR).balance(0L), + uploadInitCode(TOKEN_MISC_OPERATIONS_CONTRACT), + contractCreate(TOKEN_MISC_OPERATIONS_CONTRACT) + .gas(GAS_TO_OFFER_2) + .autoRenewAccountId(ACCOUNT), + newKeyNamed(THRESHOLD_KEY) + .shape(THRESHOLD_KEY_SHAPE.signedWith(sigs(ON, TOKEN_MISC_OPERATIONS_CONTRACT))), + cryptoUpdate(ACCOUNT).key(THRESHOLD_KEY), + cryptoUpdate(FEE_COLLECTOR).key(THRESHOLD_KEY), + cryptoUpdate(RECIPIENT).key(THRESHOLD_KEY), + cryptoUpdate(SECOND_RECIPIENT).key(THRESHOLD_KEY), + cryptoTransfer( + TokenMovement.movingHbar(ONE_HUNDRED_HBARS).between(GENESIS, TOKEN_MISC_OPERATIONS_CONTRACT)), + getContractInfo(TOKEN_MISC_OPERATIONS_CONTRACT) + .has(ContractInfoAsserts.contractWith().autoRenewAccountId(ACCOUNT)) + .logged(), + withOpContext((spec, opLog) -> allRunFor( spec, contractCall( TOKEN_MISC_OPERATIONS_CONTRACT, @@ -1053,8 +1041,8 @@ final Stream createTokenWithFixedFeeThenTransferAndAssessFee() { final var res = (Address) result[0]; createTokenNum.set(res.value().longValueExact()); }) - .hasKnownStatus(SUCCESS)))) - .then(withOpContext((spec, opLog) -> allRunFor( + .hasKnownStatus(SUCCESS))), + withOpContext((spec, opLog) -> allRunFor( spec, getTxnRecord(FIRST_CREATE_TXN).andAllChildRecords().logged(), getAccountBalance(RECIPIENT) diff --git a/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/precompile/CryptoTransferHTSSuite.java b/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/precompile/CryptoTransferHTSSuite.java index 20d2ccc41e5c..31cf7d1fbf5d 100644 --- a/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/precompile/CryptoTransferHTSSuite.java +++ b/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/contract/precompile/CryptoTransferHTSSuite.java @@ -17,7 +17,6 @@ package com.hedera.services.bdd.suites.contract.precompile; import static com.hedera.services.bdd.junit.TestTags.SMART_CONTRACT; -import static com.hedera.services.bdd.spec.HapiSpec.defaultHapiSpec; import static com.hedera.services.bdd.spec.HapiSpec.hapiTest; import static com.hedera.services.bdd.spec.assertions.AccountDetailsAsserts.accountDetailsWith; import static com.hedera.services.bdd.spec.assertions.AssertUtils.inOrder; @@ -539,21 +538,20 @@ final Stream hapiTransferFromForFungibleTokenWithInvalidAddressesFa final var TXN_FROM_NON_EXISTING_ADDRESS = "TXN_FROM_NON_EXISTING_ADDRESS"; final var TXN_WITH_NON_EXISTING_TOKEN = "TXN_WITH_NON_EXISTING_TOKEN"; - return defaultHapiSpec("hapiTransferFromForFungibleTokenWithInvalidAddressesFails") - .given( - newKeyNamed(MULTI_KEY), - cryptoCreate(OWNER).balance(100 * ONE_HUNDRED_HBARS).maxAutomaticTokenAssociations(5), - cryptoCreate(RECEIVER).maxAutomaticTokenAssociations(5), - tokenCreate(FUNGIBLE_TOKEN) - .tokenType(TokenType.FUNGIBLE_COMMON) - .supplyType(TokenSupplyType.FINITE) - .initialSupply(10L) - .maxSupply(1000L) - .supplyKey(MULTI_KEY) - .treasury(OWNER), - uploadInitCode(HTS_TRANSFER_FROM_CONTRACT), - contractCreate(HTS_TRANSFER_FROM_CONTRACT)) - .when(withOpContext((spec, opLog) -> allRunFor( + return hapiTest( + newKeyNamed(MULTI_KEY), + cryptoCreate(OWNER).balance(100 * ONE_HUNDRED_HBARS).maxAutomaticTokenAssociations(5), + cryptoCreate(RECEIVER).maxAutomaticTokenAssociations(5), + tokenCreate(FUNGIBLE_TOKEN) + .tokenType(TokenType.FUNGIBLE_COMMON) + .supplyType(TokenSupplyType.FINITE) + .initialSupply(10L) + .maxSupply(1000L) + .supplyKey(MULTI_KEY) + .treasury(OWNER), + uploadInitCode(HTS_TRANSFER_FROM_CONTRACT), + contractCreate(HTS_TRANSFER_FROM_CONTRACT), + withOpContext((spec, opLog) -> allRunFor( spec, // transfer TO address that does not exist contractCall( @@ -596,20 +594,19 @@ final Stream hapiTransferFromForFungibleTokenWithInvalidAddressesFa .gas(100_000_00L) .via(TXN_WITH_NON_EXISTING_TOKEN) .payingWith(GENESIS) - .hasKnownStatus(CONTRACT_REVERT_EXECUTED)))) - .then( - childRecordsCheck( - TXN_TO_NON_EXISTING_ADDRESS, - CONTRACT_REVERT_EXECUTED, - recordWith().status(INVALID_ALIAS_KEY)), - childRecordsCheck( - TXN_FROM_NON_EXISTING_ADDRESS, - CONTRACT_REVERT_EXECUTED, - recordWith().status(INVALID_ACCOUNT_ID)), - childRecordsCheck( - TXN_WITH_NON_EXISTING_TOKEN, - CONTRACT_REVERT_EXECUTED, - recordWith().status(INVALID_TOKEN_ID))); + .hasKnownStatus(CONTRACT_REVERT_EXECUTED))), + childRecordsCheck( + TXN_TO_NON_EXISTING_ADDRESS, + CONTRACT_REVERT_EXECUTED, + recordWith().status(INVALID_ALIAS_KEY)), + childRecordsCheck( + TXN_FROM_NON_EXISTING_ADDRESS, + CONTRACT_REVERT_EXECUTED, + recordWith().status(INVALID_ACCOUNT_ID)), + childRecordsCheck( + TXN_WITH_NON_EXISTING_TOKEN, + CONTRACT_REVERT_EXECUTED, + recordWith().status(INVALID_TOKEN_ID))); } @HapiTest @@ -620,34 +617,32 @@ final Stream hapiTransferFromForFungibleTokenWithInvalidAmountsFail final var TXN_WITH_AMOUNT_OVERFLOW_UINT = "TXN_WITH_AMOUNT_OVERFLOW_UINT"; final var allowance = 10L; - return defaultHapiSpec("hapiTransferFromForFungibleTokenWithInvalidAmountsFails") - .given( - newKeyNamed(MULTI_KEY), - cryptoCreate(OWNER).balance(100 * ONE_HUNDRED_HBARS).maxAutomaticTokenAssociations(5), - cryptoCreate(SPENDER).maxAutomaticTokenAssociations(5), - cryptoCreate(RECEIVER).maxAutomaticTokenAssociations(5), - tokenCreate(FUNGIBLE_TOKEN) - .tokenType(TokenType.FUNGIBLE_COMMON) - .supplyType(TokenSupplyType.FINITE) - .initialSupply(15L) - .maxSupply(1000L) - .supplyKey(MULTI_KEY) - .treasury(OWNER), - uploadInitCode(HTS_TRANSFER_FROM_CONTRACT), - contractCreate(HTS_TRANSFER_FROM_CONTRACT), - uploadInitCode(NEGATIVE_HTS_TRANSFER_FROM_CONTRACT), - contractCreate(NEGATIVE_HTS_TRANSFER_FROM_CONTRACT), - cryptoApproveAllowance() - .payingWith(DEFAULT_PAYER) - .addTokenAllowance(OWNER, FUNGIBLE_TOKEN, HTS_TRANSFER_FROM_CONTRACT, allowance) - .signedBy(DEFAULT_PAYER, OWNER) - .fee(ONE_HBAR), - getAccountDetails(OWNER) - .payingWith(GENESIS) - .has(accountDetailsWith() - .tokenAllowancesContaining( - FUNGIBLE_TOKEN, HTS_TRANSFER_FROM_CONTRACT, allowance))) - .when(withOpContext((spec, opLog) -> allRunFor( + return hapiTest( + newKeyNamed(MULTI_KEY), + cryptoCreate(OWNER).balance(100 * ONE_HUNDRED_HBARS).maxAutomaticTokenAssociations(5), + cryptoCreate(SPENDER).maxAutomaticTokenAssociations(5), + cryptoCreate(RECEIVER).maxAutomaticTokenAssociations(5), + tokenCreate(FUNGIBLE_TOKEN) + .tokenType(TokenType.FUNGIBLE_COMMON) + .supplyType(TokenSupplyType.FINITE) + .initialSupply(15L) + .maxSupply(1000L) + .supplyKey(MULTI_KEY) + .treasury(OWNER), + uploadInitCode(HTS_TRANSFER_FROM_CONTRACT), + contractCreate(HTS_TRANSFER_FROM_CONTRACT), + uploadInitCode(NEGATIVE_HTS_TRANSFER_FROM_CONTRACT), + contractCreate(NEGATIVE_HTS_TRANSFER_FROM_CONTRACT), + cryptoApproveAllowance() + .payingWith(DEFAULT_PAYER) + .addTokenAllowance(OWNER, FUNGIBLE_TOKEN, HTS_TRANSFER_FROM_CONTRACT, allowance) + .signedBy(DEFAULT_PAYER, OWNER) + .fee(ONE_HBAR), + getAccountDetails(OWNER) + .payingWith(GENESIS) + .has(accountDetailsWith() + .tokenAllowancesContaining(FUNGIBLE_TOKEN, HTS_TRANSFER_FROM_CONTRACT, allowance)), + withOpContext((spec, opLog) -> allRunFor( spec, // transfer with amount > allowance for the caller contractCall( @@ -710,16 +705,15 @@ final Stream hapiTransferFromForFungibleTokenWithInvalidAmountsFail .via(TXN_WITH_AMOUNT_OVERFLOW_UINT) .payingWith(GENESIS) .hasKnownStatus(CONTRACT_REVERT_EXECUTED), - emptyChildRecordsCheck(TXN_WITH_AMOUNT_OVERFLOW_UINT, CONTRACT_REVERT_EXECUTED)))) - .then( - childRecordsCheck( - TXN_WITH_AMOUNT_BIGGER_THAN_ALLOWANCE, - CONTRACT_REVERT_EXECUTED, - recordWith().status(AMOUNT_EXCEEDS_ALLOWANCE)), - childRecordsCheck( - TXN_WITH_AMOUNT_BIGGER_THAN_BALANCE, - CONTRACT_REVERT_EXECUTED, - recordWith().status(INSUFFICIENT_TOKEN_BALANCE))); + emptyChildRecordsCheck(TXN_WITH_AMOUNT_OVERFLOW_UINT, CONTRACT_REVERT_EXECUTED))), + childRecordsCheck( + TXN_WITH_AMOUNT_BIGGER_THAN_ALLOWANCE, + CONTRACT_REVERT_EXECUTED, + recordWith().status(AMOUNT_EXCEEDS_ALLOWANCE)), + childRecordsCheck( + TXN_WITH_AMOUNT_BIGGER_THAN_BALANCE, + CONTRACT_REVERT_EXECUTED, + recordWith().status(INSUFFICIENT_TOKEN_BALANCE))); } @HapiTest diff --git a/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/token/Hip17UnhappyTokensSuite.java b/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/token/Hip17UnhappyTokensSuite.java index b47259943479..8e4401040dc7 100644 --- a/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/token/Hip17UnhappyTokensSuite.java +++ b/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/token/Hip17UnhappyTokensSuite.java @@ -17,7 +17,7 @@ package com.hedera.services.bdd.suites.token; import static com.hedera.services.bdd.junit.TestTags.TOKEN; -import static com.hedera.services.bdd.spec.HapiSpec.defaultHapiSpec; +import static com.hedera.services.bdd.spec.HapiSpec.hapiTest; import static com.hedera.services.bdd.spec.queries.QueryVerbs.getAccountInfo; import static com.hedera.services.bdd.spec.queries.QueryVerbs.getTokenInfo; import static com.hedera.services.bdd.spec.queries.QueryVerbs.getTokenNftInfo; @@ -86,196 +86,186 @@ public class Hip17UnhappyTokensSuite { @HapiTest final Stream canStillGetNftInfoWhenDeleted() { - return defaultHapiSpec("canStillGetNftInfoWhenDeleted") - .given( - newKeyNamed(SUPPLY_KEY), - newKeyNamed(ADMIN_KEY), - cryptoCreate(TOKEN_TREASURY).balance(ONE_HUNDRED_HBARS), - tokenCreate(NFTdeleted) - .tokenType(NON_FUNGIBLE_UNIQUE) - .supplyType(TokenSupplyType.INFINITE) - .supplyKey(SUPPLY_KEY) - .adminKey(ADMIN_KEY) - .initialSupply(0) - .treasury(TOKEN_TREASURY), - mintToken(NFTdeleted, List.of(metadata(FIRST_MEMO)))) - .when(tokenDelete(NFTdeleted)) - .then(getTokenNftInfo(NFTdeleted, 1L).hasTokenID(NFTdeleted).hasSerialNum(1L)); + return hapiTest( + newKeyNamed(SUPPLY_KEY), + newKeyNamed(ADMIN_KEY), + cryptoCreate(TOKEN_TREASURY).balance(ONE_HUNDRED_HBARS), + tokenCreate(NFTdeleted) + .tokenType(NON_FUNGIBLE_UNIQUE) + .supplyType(TokenSupplyType.INFINITE) + .supplyKey(SUPPLY_KEY) + .adminKey(ADMIN_KEY) + .initialSupply(0) + .treasury(TOKEN_TREASURY), + mintToken(NFTdeleted, List.of(metadata(FIRST_MEMO))), + (tokenDelete(NFTdeleted)), + (getTokenNftInfo(NFTdeleted, 1L).hasTokenID(NFTdeleted).hasSerialNum(1L))); } @HapiTest final Stream cannotTransferNftWhenDeleted() { - return defaultHapiSpec("cannotTransferNftWhenDeleted") - .given( - newKeyNamed(SUPPLY_KEY), - newKeyNamed(ADMIN_KEY), - cryptoCreate(TOKEN_TREASURY), - cryptoCreate(ANOTHER_USER), - tokenCreate(NFTdeleted) - .tokenType(TokenType.NON_FUNGIBLE_UNIQUE) - .initialSupply(0) - .supplyType(TokenSupplyType.INFINITE) - .supplyKey(SUPPLY_KEY) - .adminKey(ADMIN_KEY) - .treasury(TOKEN_TREASURY)) - .when( - tokenAssociate(ANOTHER_USER, NFTdeleted), - mintToken(NFTdeleted, List.of(metadata(FIRST_MEMO), metadata(SECOND_MEMO))), - cryptoTransfer( - TokenMovement.movingUnique(NFTdeleted, 1L).between(TOKEN_TREASURY, ANOTHER_USER)), - tokenDelete(NFTdeleted)) - .then(cryptoTransfer(TokenMovement.movingUnique(NFTdeleted, 2L).between(TOKEN_TREASURY, ANOTHER_USER)) + return hapiTest( + newKeyNamed(SUPPLY_KEY), + newKeyNamed(ADMIN_KEY), + cryptoCreate(TOKEN_TREASURY), + cryptoCreate(ANOTHER_USER), + tokenCreate(NFTdeleted) + .tokenType(TokenType.NON_FUNGIBLE_UNIQUE) + .initialSupply(0) + .supplyType(TokenSupplyType.INFINITE) + .supplyKey(SUPPLY_KEY) + .adminKey(ADMIN_KEY) + .treasury(TOKEN_TREASURY), + tokenAssociate(ANOTHER_USER, NFTdeleted), + mintToken(NFTdeleted, List.of(metadata(FIRST_MEMO), metadata(SECOND_MEMO))), + cryptoTransfer(TokenMovement.movingUnique(NFTdeleted, 1L).between(TOKEN_TREASURY, ANOTHER_USER)), + tokenDelete(NFTdeleted), + cryptoTransfer(TokenMovement.movingUnique(NFTdeleted, 2L).between(TOKEN_TREASURY, ANOTHER_USER)) .hasKnownStatus(TOKEN_WAS_DELETED)); } @HapiTest final Stream cannotUnfreezeNftWhenDeleted() { - return defaultHapiSpec("cannotUnfreezeNftWhenDeleted") - .given( - newKeyNamed(SUPPLY_KEY), - newKeyNamed(FREEZE_KEY), - newKeyNamed(ADMIN_KEY), - cryptoCreate(TOKEN_TREASURY).balance(0L).key(ADMIN_KEY), - tokenCreate(NFTdeleted) - .tokenType(TokenType.NON_FUNGIBLE_UNIQUE) - .initialSupply(0L) - .freezeKey(FREEZE_KEY) - .freezeDefault(true) - .adminKey(ADMIN_KEY) - .supplyKey(SUPPLY_KEY) - .treasury(TOKEN_TREASURY)) - .when(tokenDelete(NFTdeleted)) - .then(tokenUnfreeze(NFTdeleted, TOKEN_TREASURY).hasKnownStatus(TOKEN_WAS_DELETED)); + return hapiTest( + newKeyNamed(SUPPLY_KEY), + newKeyNamed(FREEZE_KEY), + newKeyNamed(ADMIN_KEY), + cryptoCreate(TOKEN_TREASURY).balance(0L).key(ADMIN_KEY), + tokenCreate(NFTdeleted) + .tokenType(TokenType.NON_FUNGIBLE_UNIQUE) + .initialSupply(0L) + .freezeKey(FREEZE_KEY) + .freezeDefault(true) + .adminKey(ADMIN_KEY) + .supplyKey(SUPPLY_KEY) + .treasury(TOKEN_TREASURY), + tokenDelete(NFTdeleted), + tokenUnfreeze(NFTdeleted, TOKEN_TREASURY).hasKnownStatus(TOKEN_WAS_DELETED)); } @HapiTest final Stream cannotFreezeNftWhenDeleted() { - return defaultHapiSpec("cannotFreezeNftWhenDeleted") - .given( - newKeyNamed(SUPPLY_KEY), - newKeyNamed(FREEZE_KEY), - newKeyNamed(ADMIN_KEY), - cryptoCreate(TOKEN_TREASURY).balance(0L).key(ADMIN_KEY), - tokenCreate(NFTdeleted) - .tokenType(TokenType.NON_FUNGIBLE_UNIQUE) - .freezeKey(FREEZE_KEY) - .adminKey(ADMIN_KEY) - .supplyKey(SUPPLY_KEY) - .initialSupply(0L) - .treasury(TOKEN_TREASURY)) - .when(tokenDelete(NFTdeleted)) - .then(tokenFreeze(NFTdeleted, TOKEN_TREASURY).hasPrecheck(OK).hasKnownStatus(TOKEN_WAS_DELETED)); + return hapiTest( + newKeyNamed(SUPPLY_KEY), + newKeyNamed(FREEZE_KEY), + newKeyNamed(ADMIN_KEY), + cryptoCreate(TOKEN_TREASURY).balance(0L).key(ADMIN_KEY), + tokenCreate(NFTdeleted) + .tokenType(TokenType.NON_FUNGIBLE_UNIQUE) + .freezeKey(FREEZE_KEY) + .adminKey(ADMIN_KEY) + .supplyKey(SUPPLY_KEY) + .initialSupply(0L) + .treasury(TOKEN_TREASURY), + tokenDelete(NFTdeleted), + tokenFreeze(NFTdeleted, TOKEN_TREASURY).hasPrecheck(OK).hasKnownStatus(TOKEN_WAS_DELETED)); } @HapiTest final Stream cannotDissociateNftWhenDeleted() { - return defaultHapiSpec("cannotDissociateNftWhenDeleted") - .given( - newKeyNamed(ADMIN_KEY), - newKeyNamed(SUPPLY_KEY), - cryptoCreate(TOKEN_TREASURY).key(ADMIN_KEY), - cryptoCreate(ANOTHER_USER), - tokenCreate(NFTdeleted) - .initialSupply(0) - .tokenType(TokenType.NON_FUNGIBLE_UNIQUE) - .supplyType(TokenSupplyType.INFINITE) - .supplyKey(SUPPLY_KEY) - .adminKey(ADMIN_KEY) - .treasury(TOKEN_TREASURY), - tokenAssociate(ANOTHER_USER, NFTdeleted)) - .when(tokenDelete(NFTdeleted)) - .then(tokenDissociate(ANOTHER_USER, NFTdeleted).hasKnownStatus(SUCCESS)); + return hapiTest( + newKeyNamed(ADMIN_KEY), + newKeyNamed(SUPPLY_KEY), + cryptoCreate(TOKEN_TREASURY).key(ADMIN_KEY), + cryptoCreate(ANOTHER_USER), + tokenCreate(NFTdeleted) + .initialSupply(0) + .tokenType(TokenType.NON_FUNGIBLE_UNIQUE) + .supplyType(TokenSupplyType.INFINITE) + .supplyKey(SUPPLY_KEY) + .adminKey(ADMIN_KEY) + .treasury(TOKEN_TREASURY), + tokenAssociate(ANOTHER_USER, NFTdeleted), + tokenDelete(NFTdeleted), + tokenDissociate(ANOTHER_USER, NFTdeleted).hasKnownStatus(SUCCESS)); } @HapiTest final Stream cannotAssociateNftWhenDeleted() { - return defaultHapiSpec("cannotAssociateNftWhenDeleted") - .given( - newKeyNamed(ADMIN_KEY), - newKeyNamed(SUPPLY_KEY), - cryptoCreate(TOKEN_TREASURY).key(ADMIN_KEY), - cryptoCreate(ANOTHER_USER), - tokenCreate(NFTdeleted) - .initialSupply(0) - .tokenType(TokenType.NON_FUNGIBLE_UNIQUE) - .supplyType(TokenSupplyType.INFINITE) - .supplyKey(SUPPLY_KEY) - .adminKey(ADMIN_KEY) - .treasury(TOKEN_TREASURY)) - .when(tokenDelete(NFTdeleted)) - .then(tokenAssociate(ANOTHER_USER, NFTdeleted).hasKnownStatus(TOKEN_WAS_DELETED)); + return hapiTest( + newKeyNamed(ADMIN_KEY), + newKeyNamed(SUPPLY_KEY), + cryptoCreate(TOKEN_TREASURY).key(ADMIN_KEY), + cryptoCreate(ANOTHER_USER), + tokenCreate(NFTdeleted) + .initialSupply(0) + .tokenType(TokenType.NON_FUNGIBLE_UNIQUE) + .supplyType(TokenSupplyType.INFINITE) + .supplyKey(SUPPLY_KEY) + .adminKey(ADMIN_KEY) + .treasury(TOKEN_TREASURY), + tokenDelete(NFTdeleted), + tokenAssociate(ANOTHER_USER, NFTdeleted).hasKnownStatus(TOKEN_WAS_DELETED)); } @HapiTest // transferList differ final Stream cannotUpdateNftWhenDeleted() { - return defaultHapiSpec("cannotUpdateNftWhenDeleted") - .given( - cryptoCreate(TOKEN_TREASURY).balance(ONE_HUNDRED_HBARS), - cryptoCreate(NEW_TOKEN_TREASURY).balance(ONE_HUNDRED_HBARS), - cryptoCreate(AUTO_RENEW_ACCT).balance(ONE_HUNDRED_HBARS), - cryptoCreate(NEW_AUTO_RENEW_ACCT).balance(ONE_HUNDRED_HBARS), - newKeyNamed(ADMIN_KEY), - newKeyNamed(FREEZE_KEY), - newKeyNamed(NEW_FREEZE_KEY), - newKeyNamed(KYC_KEY), - newKeyNamed(NEW_KYC_KEY), - newKeyNamed(SUPPLY_KEY), - newKeyNamed(NEW_SUPPLY_KEY), - newKeyNamed(WIPE_KEY), - newKeyNamed(NEW_WIPE_KEY), - tokenCreate(NFTdeleted) - .tokenType(NON_FUNGIBLE_UNIQUE) - .supplyType(TokenSupplyType.INFINITE) - .name(SALTED_NAME) - .entityMemo(FIRST_MEMO) - .treasury(TOKEN_TREASURY) - .autoRenewAccount(AUTO_RENEW_ACCT) - .initialSupply(0) - .adminKey(ADMIN_KEY) - .freezeKey(FREEZE_KEY) - .kycKey(KYC_KEY) - .supplyKey(SUPPLY_KEY) - .wipeKey(WIPE_KEY), - tokenAssociate(NEW_TOKEN_TREASURY, NFTdeleted), - // can update before NFT is deleted - tokenUpdate(NFTdeleted) - .entityMemo(ZERO_BYTE_MEMO) - .signedByPayerAnd(ADMIN_KEY) - .hasPrecheck(INVALID_ZERO_BYTE_IN_STRING), - tokenUpdate(NFTdeleted) - .name(NEW_SALTED_NAME) - .entityMemo(SECOND_MEMO) - .treasury(NEW_TOKEN_TREASURY) - .autoRenewAccount(NEW_AUTO_RENEW_ACCT) - .freezeKey(NEW_FREEZE_KEY) - .kycKey(NEW_KYC_KEY) - .supplyKey(NEW_SUPPLY_KEY) - .wipeKey(NEW_WIPE_KEY) - .signedByPayerAnd(ADMIN_KEY, NEW_TOKEN_TREASURY, NEW_AUTO_RENEW_ACCT) - .hasKnownStatus(SUCCESS)) - .when(tokenDelete(NFTdeleted)) - .then( - // can't update after NFT is deleted. - tokenUpdate(NFTdeleted) - .name(NEW_SALTED_NAME) - .entityMemo(SECOND_MEMO) - .signedByPayerAnd(ADMIN_KEY) - .hasKnownStatus(TOKEN_WAS_DELETED), - tokenUpdate(NFTdeleted) - .treasury(NEW_TOKEN_TREASURY) - .signedByPayerAnd(ADMIN_KEY, NEW_TOKEN_TREASURY) - .hasKnownStatus(TOKEN_WAS_DELETED), - tokenUpdate(NFTdeleted) - .autoRenewAccount(NEW_AUTO_RENEW_ACCT) - .signedByPayerAnd(ADMIN_KEY, NEW_AUTO_RENEW_ACCT) - .hasKnownStatus(TOKEN_WAS_DELETED), - tokenUpdate(NFTdeleted) - .freezeKey(NEW_FREEZE_KEY) - .kycKey(NEW_KYC_KEY) - .supplyKey(NEW_SUPPLY_KEY) - .wipeKey(NEW_WIPE_KEY) - .signedByPayerAnd(ADMIN_KEY) - .hasKnownStatus(TOKEN_WAS_DELETED)); + return hapiTest( + cryptoCreate(TOKEN_TREASURY).balance(ONE_HUNDRED_HBARS), + cryptoCreate(NEW_TOKEN_TREASURY).balance(ONE_HUNDRED_HBARS), + cryptoCreate(AUTO_RENEW_ACCT).balance(ONE_HUNDRED_HBARS), + cryptoCreate(NEW_AUTO_RENEW_ACCT).balance(ONE_HUNDRED_HBARS), + newKeyNamed(ADMIN_KEY), + newKeyNamed(FREEZE_KEY), + newKeyNamed(NEW_FREEZE_KEY), + newKeyNamed(KYC_KEY), + newKeyNamed(NEW_KYC_KEY), + newKeyNamed(SUPPLY_KEY), + newKeyNamed(NEW_SUPPLY_KEY), + newKeyNamed(WIPE_KEY), + newKeyNamed(NEW_WIPE_KEY), + tokenCreate(NFTdeleted) + .tokenType(NON_FUNGIBLE_UNIQUE) + .supplyType(TokenSupplyType.INFINITE) + .name(SALTED_NAME) + .entityMemo(FIRST_MEMO) + .treasury(TOKEN_TREASURY) + .autoRenewAccount(AUTO_RENEW_ACCT) + .initialSupply(0) + .adminKey(ADMIN_KEY) + .freezeKey(FREEZE_KEY) + .kycKey(KYC_KEY) + .supplyKey(SUPPLY_KEY) + .wipeKey(WIPE_KEY), + tokenAssociate(NEW_TOKEN_TREASURY, NFTdeleted), + // can update before NFT is deleted + tokenUpdate(NFTdeleted) + .entityMemo(ZERO_BYTE_MEMO) + .signedByPayerAnd(ADMIN_KEY) + .hasPrecheck(INVALID_ZERO_BYTE_IN_STRING), + tokenUpdate(NFTdeleted) + .name(NEW_SALTED_NAME) + .entityMemo(SECOND_MEMO) + .treasury(NEW_TOKEN_TREASURY) + .autoRenewAccount(NEW_AUTO_RENEW_ACCT) + .freezeKey(NEW_FREEZE_KEY) + .kycKey(NEW_KYC_KEY) + .supplyKey(NEW_SUPPLY_KEY) + .wipeKey(NEW_WIPE_KEY) + .signedByPayerAnd(ADMIN_KEY, NEW_TOKEN_TREASURY, NEW_AUTO_RENEW_ACCT) + .hasKnownStatus(SUCCESS), + tokenDelete(NFTdeleted), + // can't update after NFT is deleted. + tokenUpdate(NFTdeleted) + .name(NEW_SALTED_NAME) + .entityMemo(SECOND_MEMO) + .signedByPayerAnd(ADMIN_KEY) + .hasKnownStatus(TOKEN_WAS_DELETED), + tokenUpdate(NFTdeleted) + .treasury(NEW_TOKEN_TREASURY) + .signedByPayerAnd(ADMIN_KEY, NEW_TOKEN_TREASURY) + .hasKnownStatus(TOKEN_WAS_DELETED), + tokenUpdate(NFTdeleted) + .autoRenewAccount(NEW_AUTO_RENEW_ACCT) + .signedByPayerAnd(ADMIN_KEY, NEW_AUTO_RENEW_ACCT) + .hasKnownStatus(TOKEN_WAS_DELETED), + tokenUpdate(NFTdeleted) + .freezeKey(NEW_FREEZE_KEY) + .kycKey(NEW_KYC_KEY) + .supplyKey(NEW_SUPPLY_KEY) + .wipeKey(NEW_WIPE_KEY) + .signedByPayerAnd(ADMIN_KEY) + .hasKnownStatus(TOKEN_WAS_DELETED)); } @HapiTest @@ -284,109 +274,103 @@ final Stream cannotUpdateNftFeeScheduleWhenDeleted() { final var newHbarFee = 4_321L; final var hbarCollector = "hbarFee"; - return defaultHapiSpec("cannotUpdateNftFeeScheduleWhenDeleted") - .given( - newKeyNamed(ADMIN_KEY), - newKeyNamed(FEE_SCHEDULE_KEY), - newKeyNamed(SUPPLY_KEY), - cryptoCreate(TOKEN_TREASURY).key(ADMIN_KEY), - cryptoCreate(hbarCollector), - tokenCreate(NFTdeleted) - .tokenType(NON_FUNGIBLE_UNIQUE) - .initialSupply(0L) - .adminKey(ADMIN_KEY) - .treasury(TOKEN_TREASURY) - .supplyKey(SUPPLY_KEY) - .feeScheduleKey(FEE_SCHEDULE_KEY) - .withCustom(fixedHbarFee(origHbarFee, hbarCollector))) - .when(tokenDelete(NFTdeleted)) - .then(tokenFeeScheduleUpdate(NFTdeleted) + return hapiTest( + newKeyNamed(ADMIN_KEY), + newKeyNamed(FEE_SCHEDULE_KEY), + newKeyNamed(SUPPLY_KEY), + cryptoCreate(TOKEN_TREASURY).key(ADMIN_KEY), + cryptoCreate(hbarCollector), + tokenCreate(NFTdeleted) + .tokenType(NON_FUNGIBLE_UNIQUE) + .initialSupply(0L) + .adminKey(ADMIN_KEY) + .treasury(TOKEN_TREASURY) + .supplyKey(SUPPLY_KEY) + .feeScheduleKey(FEE_SCHEDULE_KEY) + .withCustom(fixedHbarFee(origHbarFee, hbarCollector)), + tokenDelete(NFTdeleted), + tokenFeeScheduleUpdate(NFTdeleted) .withCustom(fixedHbarFee(newHbarFee, hbarCollector)) .hasKnownStatus(TOKEN_WAS_DELETED)); } @HapiTest final Stream cannotMintNftWhenDeleted() { - return defaultHapiSpec("cannotMintNftWhenDeleted") - .given( - newKeyNamed(SUPPLY_KEY), - newKeyNamed(WIPE_KEY), - newKeyNamed(ADMIN_KEY), - cryptoCreate(TOKEN_TREASURY).key(ADMIN_KEY), - cryptoCreate(ANOTHER_USER), - tokenCreate(NFTdeleted) - .tokenType(NON_FUNGIBLE_UNIQUE) - .supplyType(TokenSupplyType.INFINITE) - .supplyKey(SUPPLY_KEY) - .initialSupply(0) - .treasury(TOKEN_TREASURY) - .adminKey(ADMIN_KEY)) - .when(tokenDelete(NFTdeleted)) - .then(mintToken(NFTdeleted, List.of(ByteString.copyFromUtf8(FIRST_MEMO))) + return hapiTest( + newKeyNamed(SUPPLY_KEY), + newKeyNamed(WIPE_KEY), + newKeyNamed(ADMIN_KEY), + cryptoCreate(TOKEN_TREASURY).key(ADMIN_KEY), + cryptoCreate(ANOTHER_USER), + tokenCreate(NFTdeleted) + .tokenType(NON_FUNGIBLE_UNIQUE) + .supplyType(TokenSupplyType.INFINITE) + .supplyKey(SUPPLY_KEY) + .initialSupply(0) + .treasury(TOKEN_TREASURY) + .adminKey(ADMIN_KEY), + tokenDelete(NFTdeleted), + mintToken(NFTdeleted, List.of(ByteString.copyFromUtf8(FIRST_MEMO))) .hasKnownStatus(TOKEN_WAS_DELETED)); } @HapiTest final Stream cannotBurnNftWhenDeleted() { - return defaultHapiSpec("cannotBurnNftWhenDeleted") - .given( - newKeyNamed(SUPPLY_KEY), - newKeyNamed(WIPE_KEY), - newKeyNamed(ADMIN_KEY), - newKeyNamed(ANOTHER_KEY), - cryptoCreate(TOKEN_TREASURY).key(ADMIN_KEY), - cryptoCreate(ANOTHER_USER).key(ANOTHER_KEY), - tokenCreate(NFTdeleted) - .tokenType(NON_FUNGIBLE_UNIQUE) - .supplyType(TokenSupplyType.INFINITE) - .supplyKey(SUPPLY_KEY) - .initialSupply(0) - .treasury(TOKEN_TREASURY) - .adminKey(ADMIN_KEY), - tokenAssociate(ANOTHER_USER, NFTdeleted), - mintToken( - NFTdeleted, - List.of(ByteString.copyFromUtf8(FIRST_MEMO), ByteString.copyFromUtf8(SECOND_MEMO))), - cryptoTransfer(movingUnique(NFTdeleted, 2L).between(TOKEN_TREASURY, ANOTHER_USER)), - getAccountInfo(ANOTHER_USER).hasOwnedNfts(1), - getAccountInfo(TOKEN_TREASURY).hasOwnedNfts(1), - getTokenInfo(NFTdeleted).hasTotalSupply(2), - getTokenNftInfo(NFTdeleted, 2).hasCostAnswerPrecheck(OK), - getTokenNftInfo(NFTdeleted, 1).hasSerialNum(1)) - .when(tokenDelete(NFTdeleted)) - .then(burnToken(NFTdeleted, List.of(2L)).hasKnownStatus(TOKEN_WAS_DELETED)); + return hapiTest( + newKeyNamed(SUPPLY_KEY), + newKeyNamed(WIPE_KEY), + newKeyNamed(ADMIN_KEY), + newKeyNamed(ANOTHER_KEY), + cryptoCreate(TOKEN_TREASURY).key(ADMIN_KEY), + cryptoCreate(ANOTHER_USER).key(ANOTHER_KEY), + tokenCreate(NFTdeleted) + .tokenType(NON_FUNGIBLE_UNIQUE) + .supplyType(TokenSupplyType.INFINITE) + .supplyKey(SUPPLY_KEY) + .initialSupply(0) + .treasury(TOKEN_TREASURY) + .adminKey(ADMIN_KEY), + tokenAssociate(ANOTHER_USER, NFTdeleted), + mintToken( + NFTdeleted, List.of(ByteString.copyFromUtf8(FIRST_MEMO), ByteString.copyFromUtf8(SECOND_MEMO))), + cryptoTransfer(movingUnique(NFTdeleted, 2L).between(TOKEN_TREASURY, ANOTHER_USER)), + getAccountInfo(ANOTHER_USER).hasOwnedNfts(1), + getAccountInfo(TOKEN_TREASURY).hasOwnedNfts(1), + getTokenInfo(NFTdeleted).hasTotalSupply(2), + getTokenNftInfo(NFTdeleted, 2).hasCostAnswerPrecheck(OK), + getTokenNftInfo(NFTdeleted, 1).hasSerialNum(1), + tokenDelete(NFTdeleted), + burnToken(NFTdeleted, List.of(2L)).hasKnownStatus(TOKEN_WAS_DELETED)); } @HapiTest final Stream cannotWipeNftWhenDeleted() { - return defaultHapiSpec("cannotWipeNftWhenDeleted") - .given( - newKeyNamed(SUPPLY_KEY), - newKeyNamed(WIPE_KEY), - newKeyNamed(ADMIN_KEY), - newKeyNamed(ANOTHER_KEY), - cryptoCreate(TOKEN_TREASURY).key(ADMIN_KEY), - cryptoCreate(ANOTHER_USER).key(ANOTHER_KEY), - tokenCreate(NFTdeleted) - .tokenType(NON_FUNGIBLE_UNIQUE) - .supplyType(TokenSupplyType.INFINITE) - .supplyKey(SUPPLY_KEY) - .initialSupply(0) - .treasury(TOKEN_TREASURY) - .adminKey(ADMIN_KEY) - .wipeKey(WIPE_KEY), - tokenAssociate(ANOTHER_USER, NFTdeleted), - mintToken( - NFTdeleted, - List.of(ByteString.copyFromUtf8(FIRST_MEMO), ByteString.copyFromUtf8(SECOND_MEMO))), - cryptoTransfer(movingUnique(NFTdeleted, 2L).between(TOKEN_TREASURY, ANOTHER_USER)), - getAccountInfo(ANOTHER_USER).hasOwnedNfts(1), - getAccountInfo(TOKEN_TREASURY).hasOwnedNfts(1), - getTokenInfo(NFTdeleted).hasTotalSupply(2), - getTokenNftInfo(NFTdeleted, 2).hasCostAnswerPrecheck(OK), - getTokenNftInfo(NFTdeleted, 1).hasSerialNum(1)) - .when(tokenDelete(NFTdeleted)) - .then(wipeTokenAccount(NFTdeleted, ANOTHER_USER, List.of(1L)).hasKnownStatus(TOKEN_WAS_DELETED)); + return hapiTest( + newKeyNamed(SUPPLY_KEY), + newKeyNamed(WIPE_KEY), + newKeyNamed(ADMIN_KEY), + newKeyNamed(ANOTHER_KEY), + cryptoCreate(TOKEN_TREASURY).key(ADMIN_KEY), + cryptoCreate(ANOTHER_USER).key(ANOTHER_KEY), + tokenCreate(NFTdeleted) + .tokenType(NON_FUNGIBLE_UNIQUE) + .supplyType(TokenSupplyType.INFINITE) + .supplyKey(SUPPLY_KEY) + .initialSupply(0) + .treasury(TOKEN_TREASURY) + .adminKey(ADMIN_KEY) + .wipeKey(WIPE_KEY), + tokenAssociate(ANOTHER_USER, NFTdeleted), + mintToken( + NFTdeleted, List.of(ByteString.copyFromUtf8(FIRST_MEMO), ByteString.copyFromUtf8(SECOND_MEMO))), + cryptoTransfer(movingUnique(NFTdeleted, 2L).between(TOKEN_TREASURY, ANOTHER_USER)), + getAccountInfo(ANOTHER_USER).hasOwnedNfts(1), + getAccountInfo(TOKEN_TREASURY).hasOwnedNfts(1), + getTokenInfo(NFTdeleted).hasTotalSupply(2), + getTokenNftInfo(NFTdeleted, 2).hasCostAnswerPrecheck(OK), + getTokenNftInfo(NFTdeleted, 1).hasSerialNum(1), + tokenDelete(NFTdeleted), + wipeTokenAccount(NFTdeleted, ANOTHER_USER, List.of(1L)).hasKnownStatus(TOKEN_WAS_DELETED)); } private ByteString metadata(String contents) {