|
24 | 24 | #include "transactions/TransactionBridge.h" |
25 | 25 | #include "transactions/TransactionUtils.h" |
26 | 26 | #include "transactions/test/SorobanTxTestUtils.h" |
| 27 | +#include "util/ProtocolVersion.h" |
27 | 28 | #include "util/Timer.h" |
28 | 29 | #include "util/numeric128.h" |
29 | 30 | #include "xdr/Stellar-transaction.h" |
@@ -1264,50 +1265,65 @@ TEST_CASE("Soroban tx filtering", "[soroban][transactionqueue]") |
1264 | 1265 | TransactionQueue::AddResultCode::ADD_STATUS_ERROR); |
1265 | 1266 | } |
1266 | 1267 |
|
1267 | | - auto runInvalidCreateContractTest = |
1268 | | - [&](HostFunctionType hostFnType, ContractIDPreimageType preimageType, |
1269 | | - ContractExecutableType executableType) { |
1270 | | - Operation createOp; |
1271 | | - createOp.body.type(INVOKE_HOST_FUNCTION); |
1272 | | - auto& createHF = createOp.body.invokeHostFunctionOp().hostFunction; |
1273 | | - createHF.type(hostFnType); |
1274 | | - |
1275 | | - auto setPreimageAndExecutable = [&](ContractIDPreimage& preimage, |
1276 | | - ContractExecutable& exec) { |
1277 | | - preimage.type(preimageType); |
1278 | | - if (preimageType == CONTRACT_ID_PREIMAGE_FROM_ASSET) |
1279 | | - { |
1280 | | - preimage.fromAsset() = makeNativeAsset(); |
1281 | | - } |
1282 | | - else |
1283 | | - { |
1284 | | - preimage.fromAddress().address = |
1285 | | - makeAccountAddress(a1.getPublicKey()); |
1286 | | - preimage.fromAddress().salt = sha256("salt"); |
1287 | | - } |
1288 | | - exec.type(executableType); |
1289 | | - if (executableType == CONTRACT_EXECUTABLE_WASM) |
1290 | | - { |
1291 | | - exec.wasm_hash() = sha256(wasm.data); |
1292 | | - } |
1293 | | - }; |
| 1268 | + auto makeCreateContractTx = [&](HostFunctionType hostFnType, |
| 1269 | + ContractIDPreimageType preimageType, |
| 1270 | + ContractExecutableType executableType) { |
| 1271 | + Operation createOp; |
| 1272 | + createOp.body.type(INVOKE_HOST_FUNCTION); |
| 1273 | + auto& createHF = createOp.body.invokeHostFunctionOp().hostFunction; |
| 1274 | + createHF.type(hostFnType); |
1294 | 1275 |
|
1295 | | - if (hostFnType == HOST_FUNCTION_TYPE_CREATE_CONTRACT) |
| 1276 | + auto setPreimageAndExecutable = [&](ContractIDPreimage& preimage, |
| 1277 | + ContractExecutable& exec) { |
| 1278 | + preimage.type(preimageType); |
| 1279 | + if (preimageType == CONTRACT_ID_PREIMAGE_FROM_ASSET) |
1296 | 1280 | { |
1297 | | - setPreimageAndExecutable( |
1298 | | - createHF.createContract().contractIDPreimage, |
1299 | | - createHF.createContract().executable); |
| 1281 | + preimage.fromAsset() = makeNativeAsset(); |
1300 | 1282 | } |
1301 | 1283 | else |
1302 | 1284 | { |
1303 | | - setPreimageAndExecutable( |
1304 | | - createHF.createContractV2().contractIDPreimage, |
1305 | | - createHF.createContractV2().executable); |
| 1285 | + preimage.fromAddress().address = |
| 1286 | + makeAccountAddress(a1.getPublicKey()); |
| 1287 | + preimage.fromAddress().salt = sha256("salt"); |
1306 | 1288 | } |
| 1289 | + exec.type(executableType); |
| 1290 | + if (executableType == CONTRACT_EXECUTABLE_WASM) |
| 1291 | + { |
| 1292 | + exec.wasm_hash() = sha256(wasm.data); |
| 1293 | + } |
| 1294 | +#ifdef CAP_0085_EXECUTABLE_REF |
| 1295 | + else if (executableType == CONTRACT_EXECUTABLE_EXTERNAL_REF) |
| 1296 | + { |
| 1297 | + exec.external_ref().executable_owner = |
| 1298 | + makeContractAddress(sha256("owner")); |
| 1299 | + exec.external_ref().tag = "tag"; |
| 1300 | + } |
| 1301 | +#endif |
| 1302 | + }; |
1307 | 1303 |
|
1308 | | - auto tx = sorobanTransactionFrameFromOpsWithTotalFee( |
1309 | | - app->getNetworkID(), a1, {createOp}, {}, resources, |
1310 | | - uploadResourceFee + 100, uploadResourceFee); |
| 1304 | + if (hostFnType == HOST_FUNCTION_TYPE_CREATE_CONTRACT) |
| 1305 | + { |
| 1306 | + setPreimageAndExecutable( |
| 1307 | + createHF.createContract().contractIDPreimage, |
| 1308 | + createHF.createContract().executable); |
| 1309 | + } |
| 1310 | + else |
| 1311 | + { |
| 1312 | + setPreimageAndExecutable( |
| 1313 | + createHF.createContractV2().contractIDPreimage, |
| 1314 | + createHF.createContractV2().executable); |
| 1315 | + } |
| 1316 | + |
| 1317 | + return sorobanTransactionFrameFromOpsWithTotalFee( |
| 1318 | + app->getNetworkID(), a1, {createOp}, {}, resources, |
| 1319 | + uploadResourceFee + 100, uploadResourceFee); |
| 1320 | + }; |
| 1321 | + |
| 1322 | + auto runInvalidCreateContractTest = |
| 1323 | + [&](HostFunctionType hostFnType, ContractIDPreimageType preimageType, |
| 1324 | + ContractExecutableType executableType) { |
| 1325 | + auto tx = |
| 1326 | + makeCreateContractTx(hostFnType, preimageType, executableType); |
1311 | 1327 | auto feeBumpTx = |
1312 | 1328 | feeBump(*app, feeBumper, tx, uploadResourceFee + 200); |
1313 | 1329 |
|
@@ -1336,6 +1352,35 @@ TEST_CASE("Soroban tx filtering", "[soroban][transactionqueue]") |
1336 | 1352 | CONTRACT_ID_PREIMAGE_FROM_ADDRESS, |
1337 | 1353 | CONTRACT_EXECUTABLE_STELLAR_ASSET); |
1338 | 1354 | } |
| 1355 | + |
| 1356 | +#ifdef CAP_0085_EXECUTABLE_REF |
| 1357 | + SECTION("CAP-0085 external ref executable") |
| 1358 | + { |
| 1359 | + uint32_t const gate = |
| 1360 | + static_cast<uint32_t>(EXTERNAL_EXECUTABLE_REF_PROTOCOL_VERSION); |
| 1361 | + |
| 1362 | + // FROM_ADDRESS + external ref is accepted starting at the CAP-0085 |
| 1363 | + // protocol version and rejected just below it, for both host-fn |
| 1364 | + // variants. |
| 1365 | + for (auto hostFnType : {HOST_FUNCTION_TYPE_CREATE_CONTRACT, |
| 1366 | + HOST_FUNCTION_TYPE_CREATE_CONTRACT_V2}) |
| 1367 | + { |
| 1368 | + auto tx = makeCreateContractTx(hostFnType, |
| 1369 | + CONTRACT_ID_PREIMAGE_FROM_ADDRESS, |
| 1370 | + CONTRACT_EXECUTABLE_EXTERNAL_REF); |
| 1371 | + REQUIRE(tx->validateHostFn(gate)); |
| 1372 | + REQUIRE_FALSE(tx->validateHostFn(gate - 1)); |
| 1373 | + } |
| 1374 | + |
| 1375 | + // FROM_ASSET + external ref stays rejected. |
| 1376 | + runInvalidCreateContractTest(HOST_FUNCTION_TYPE_CREATE_CONTRACT, |
| 1377 | + CONTRACT_ID_PREIMAGE_FROM_ASSET, |
| 1378 | + CONTRACT_EXECUTABLE_EXTERNAL_REF); |
| 1379 | + runInvalidCreateContractTest(HOST_FUNCTION_TYPE_CREATE_CONTRACT_V2, |
| 1380 | + CONTRACT_ID_PREIMAGE_FROM_ASSET, |
| 1381 | + CONTRACT_EXECUTABLE_EXTERNAL_REF); |
| 1382 | + } |
| 1383 | +#endif |
1339 | 1384 | } |
1340 | 1385 |
|
1341 | 1386 | TEST_CASE("TransactionQueue Key Filtering", "[soroban][transactionqueue]") |
|
0 commit comments