17
17
package com .hedera .services .bdd .suites .leaky ;
18
18
19
19
import static com .hedera .services .bdd .junit .TestTags .SMART_CONTRACT ;
20
+ import static com .hedera .services .bdd .spec .HapiPropertySource .asContractIdWithEvmAddress ;
20
21
import static com .hedera .services .bdd .spec .HapiSpec .propertyPreservingHapiSpec ;
21
22
import static com .hedera .services .bdd .spec .assertions .TransactionRecordAsserts .recordWith ;
22
23
import static com .hedera .services .bdd .spec .keys .KeyFactory .KeyType .THRESHOLD ;
25
26
import static com .hedera .services .bdd .spec .transactions .TxnVerbs .cryptoCreate ;
26
27
import static com .hedera .services .bdd .spec .transactions .TxnVerbs .cryptoTransfer ;
27
28
import static com .hedera .services .bdd .spec .transactions .TxnVerbs .ethereumCall ;
29
+ import static com .hedera .services .bdd .spec .transactions .TxnVerbs .ethereumCallWithFunctionAbi ;
30
+ import static com .hedera .services .bdd .spec .transactions .TxnVerbs .tokenAssociate ;
31
+ import static com .hedera .services .bdd .spec .transactions .TxnVerbs .tokenCreate ;
28
32
import static com .hedera .services .bdd .spec .transactions .TxnVerbs .uploadInitCode ;
33
+ import static com .hedera .services .bdd .spec .transactions .contract .HapiParserUtil .asHeadlongAddress ;
29
34
import static com .hedera .services .bdd .spec .transactions .crypto .HapiCryptoTransfer .tinyBarsFromAccountToAlias ;
35
+ import static com .hedera .services .bdd .spec .transactions .token .TokenMovement .moving ;
30
36
import static com .hedera .services .bdd .spec .utilops .CustomSpecAssert .allRunFor ;
31
37
import static com .hedera .services .bdd .spec .utilops .UtilVerbs .newKeyNamed ;
32
38
import static com .hedera .services .bdd .spec .utilops .UtilVerbs .overriding ;
33
39
import static com .hedera .services .bdd .spec .utilops .UtilVerbs .resetToDefault ;
34
40
import static com .hedera .services .bdd .spec .utilops .UtilVerbs .withOpContext ;
35
41
import static com .hedera .services .bdd .spec .utilops .records .SnapshotMatchMode .NONDETERMINISTIC_CONTRACT_CALL_RESULTS ;
36
42
import static com .hedera .services .bdd .spec .utilops .records .SnapshotMatchMode .NONDETERMINISTIC_ETHEREUM_DATA ;
43
+ import static com .hedera .services .bdd .suites .contract .Utils .FunctionType .FUNCTION ;
44
+ import static com .hedera .services .bdd .suites .contract .Utils .asAddress ;
45
+ import static com .hedera .services .bdd .suites .contract .Utils .getABIFor ;
46
+ import static com .hedera .services .bdd .suites .crypto .CryptoCreateSuite .ACCOUNT ;
47
+ import static com .hedera .services .bdd .suites .leaky .LeakyContractTestsSuite .RECEIVER ;
48
+ import static com .hedera .services .bdd .suites .token .TokenAssociationSpecs .VANILLA_TOKEN ;
49
+ import static com .hedera .services .bdd .suites .token .TokenTransactSpecs .SUPPLY_KEY ;
37
50
import static com .hederahashgraph .api .proto .java .ResponseCodeEnum .SUCCESS ;
51
+ import static com .hederahashgraph .api .proto .java .TokenType .FUNGIBLE_COMMON ;
52
+ import static com .swirlds .common .utility .CommonUtils .unhex ;
38
53
54
+ import com .google .protobuf .ByteString ;
39
55
import com .hedera .node .app .hapi .utils .ethereum .EthTxData .EthTransactionType ;
40
56
import com .hedera .services .bdd .junit .HapiTest ;
41
57
import com .hedera .services .bdd .junit .HapiTestSuite ;
42
58
import com .hedera .services .bdd .spec .HapiSpec ;
59
+ import com .hedera .services .bdd .spec .transactions .contract .HapiParserUtil ;
43
60
import com .hedera .services .bdd .suites .HapiSuite ;
44
61
import com .hederahashgraph .api .proto .java .ResponseCodeEnum ;
45
62
import java .math .BigInteger ;
@@ -56,6 +73,10 @@ public class LeakyEthereumTestsSuite extends HapiSuite {
56
73
57
74
private static final String PAY_RECEIVABLE_CONTRACT = "PayReceivable" ;
58
75
private static final Logger log = LogManager .getLogger (LeakyEthereumTestsSuite .class );
76
+ private static final String EVM_VERSION_PROPERTY = "contracts.evm.version" ;
77
+ private static final String ALLOW_CALLS_TO_NON_CONTRACT_ACCOUNTS = "contracts.evm.allowCallsToNonContractAccounts" ;
78
+ private static final String DYNAMIC_EVM_PROPERTY = "contracts.evm.version.dynamic" ;
79
+ private static final String EVM_VERSION_046 = "v0.46" ;
59
80
60
81
public static void main (String ... args ) {
61
82
new LeakyEthereumTestsSuite ().runSuiteAsync ();
@@ -68,7 +89,7 @@ public boolean canRunConcurrent() {
68
89
69
90
@ Override
70
91
public List <HapiSpec > getSpecsInSuite () {
71
- return Stream .of (legacyUnprotectedEtxBeforeEIP155 (), legacyEtxAfterEIP155 ())
92
+ return Stream .of (legacyUnprotectedEtxBeforeEIP155 (), legacyEtxAfterEIP155 (), callHtsSystemContractTest () )
72
93
.toList ();
73
94
}
74
95
@@ -166,6 +187,64 @@ HapiSpec legacyEtxAfterEIP155() {
166
187
resetToDefault (CHAIN_ID_PROP ));
167
188
}
168
189
190
+ @ HapiTest
191
+ final HapiSpec callHtsSystemContractTest () {
192
+ final var callHtsSystemContractTxn = "callHtsSystemContractTxn" ;
193
+ final var function = getABIFor (FUNCTION , "transferToken" , "IHederaTokenService" );
194
+ final var HTS_SYSTEM_CONTRACT = "hts" ;
195
+ final var HTS_SYSTEM_CONTRACT_ADDRESS = "0000000000000000000000000000000000000167" ;
196
+
197
+ return propertyPreservingHapiSpec ("callHtsSystemContractTest" )
198
+ .preserving (EVM_VERSION_PROPERTY , DYNAMIC_EVM_PROPERTY , ALLOW_CALLS_TO_NON_CONTRACT_ACCOUNTS )
199
+ .given (
200
+ overriding (DYNAMIC_EVM_PROPERTY , "true" ),
201
+ overriding (EVM_VERSION_PROPERTY , EVM_VERSION_046 ),
202
+ overriding (ALLOW_CALLS_TO_NON_CONTRACT_ACCOUNTS , "true" ),
203
+ newKeyNamed (SECP_256K1_SOURCE_KEY ).shape (SECP_256K1_SHAPE ),
204
+ newKeyNamed (SUPPLY_KEY ),
205
+ cryptoTransfer (tinyBarsFromAccountToAlias (GENESIS , SECP_256K1_SOURCE_KEY , ONE_HUNDRED_HBARS )),
206
+ cryptoCreate (RELAYER ).balance (6 * ONE_MILLION_HBARS ),
207
+ cryptoCreate (ACCOUNT ).balance (6 * ONE_MILLION_HBARS ),
208
+ cryptoCreate (TOKEN_TREASURY ),
209
+ cryptoCreate (RECEIVER ),
210
+ tokenCreate (VANILLA_TOKEN )
211
+ .tokenType (FUNGIBLE_COMMON )
212
+ .treasury (TOKEN_TREASURY )
213
+ .supplyKey (SUPPLY_KEY )
214
+ .initialSupply (1_000 ),
215
+ tokenAssociate (ACCOUNT , VANILLA_TOKEN ),
216
+ tokenAssociate (RECEIVER , VANILLA_TOKEN ),
217
+ cryptoTransfer (moving (500 , VANILLA_TOKEN ).between (TOKEN_TREASURY , ACCOUNT )))
218
+ .when (withOpContext ((spec , opLog ) -> {
219
+ final var receiver1 =
220
+ asHeadlongAddress (asAddress (spec .registry ().getAccountID (RECEIVER )));
221
+ final var sender =
222
+ asHeadlongAddress (asAddress (spec .registry ().getAccountID (ACCOUNT )));
223
+
224
+ spec .registry ()
225
+ .saveContractId (
226
+ HTS_SYSTEM_CONTRACT ,
227
+ asContractIdWithEvmAddress (
228
+ ByteString .copyFrom (unhex (HTS_SYSTEM_CONTRACT_ADDRESS ))));
229
+ allRunFor (
230
+ spec ,
231
+ ethereumCallWithFunctionAbi (
232
+ false ,
233
+ HTS_SYSTEM_CONTRACT ,
234
+ function ,
235
+ HapiParserUtil .asHeadlongAddress (
236
+ asAddress (spec .registry ().getTokenID (VANILLA_TOKEN ))),
237
+ sender ,
238
+ receiver1 ,
239
+ 1L )
240
+ .payingWith (RELAYER )
241
+ .type (EthTransactionType .EIP1559 )
242
+ .via (callHtsSystemContractTxn )
243
+ .hasKnownStatus (SUCCESS ));
244
+ }))
245
+ .then ();
246
+ }
247
+
169
248
@ Override
170
249
protected Logger getResultsLogger () {
171
250
return log ;
0 commit comments