From 2217875a232b8b94262c254f5e81248dd64153f5 Mon Sep 17 00:00:00 2001 From: Farhad Shahabi Date: Wed, 8 Sep 2021 17:37:39 -0400 Subject: [PATCH 1/8] GH-524 Merge pull request #10635 from EOSIO/nested_container_support_set_optional Cleos support for set> and vector> --- libraries/chain/abi_serializer.cpp | 6 +- libraries/testing/contracts.hpp.in | 2 + tests/CMakeLists.txt | 50 + tests/nested_container_kv_test.py | 392 ++++++ tests/nested_container_multi_index_test.py | 393 ++++++ unittests/abi_tests.cpp | 13 +- unittests/test-contracts/CMakeLists.txt | 3 + .../nested_container_kv/CMakeLists.txt | 6 + .../nested_container_kv.abi | 1212 +++++++++++++++++ .../nested_container_kv.cpp | 402 ++++++ .../nested_container_kv.wasm | Bin 0 -> 212741 bytes .../CMakeLists.txt | 6 + .../nested_container_multi_index.abi | 1195 ++++++++++++++++ .../nested_container_multi_index.cpp | 356 +++++ .../nested_container_multi_index.wasm | Bin 0 -> 227446 bytes 15 files changed, 4025 insertions(+), 11 deletions(-) create mode 100755 tests/nested_container_kv_test.py create mode 100755 tests/nested_container_multi_index_test.py create mode 100644 unittests/test-contracts/nested_container_kv/CMakeLists.txt create mode 100644 unittests/test-contracts/nested_container_kv/nested_container_kv.abi create mode 100644 unittests/test-contracts/nested_container_kv/nested_container_kv.cpp create mode 100755 unittests/test-contracts/nested_container_kv/nested_container_kv.wasm create mode 100644 unittests/test-contracts/nested_container_multi_index/CMakeLists.txt create mode 100644 unittests/test-contracts/nested_container_multi_index/nested_container_multi_index.abi create mode 100644 unittests/test-contracts/nested_container_multi_index/nested_container_multi_index.cpp create mode 100755 unittests/test-contracts/nested_container_multi_index/nested_container_multi_index.wasm diff --git a/libraries/chain/abi_serializer.cpp b/libraries/chain/abi_serializer.cpp index 94ff75a72e..cd55561d9c 100644 --- a/libraries/chain/abi_serializer.cpp +++ b/libraries/chain/abi_serializer.cpp @@ -412,10 +412,8 @@ namespace eosio { namespace chain { for( decltype(size.value) i = 0; i < size; ++i ) { ctx.set_array_index_of_path_back(i); auto v = _binary_to_variant(ftype, stream, ctx); - // QUESTION: Is it actually desired behavior to require the returned variant to not be null? - // This would disallow arrays of optionals in general (though if all optionals in the array were present it would be allowed). - // Is there any scenario in which the returned variant would be null other than in the case of an empty optional? - EOS_ASSERT( !v.is_null(), unpack_exception, "Invalid packed array '${p}'", ("p", ctx.get_path_string()) ); + // The exception below is commented out to allow array of optional as input data + //EOS_ASSERT( !v.is_null(), unpack_exception, "Invalid packed array '${p}'", ("p", ctx.get_path_string()) ); vars.emplace_back(std::move(v)); } // QUESTION: Why would the assert below ever fail? diff --git a/libraries/testing/contracts.hpp.in b/libraries/testing/contracts.hpp.in index 3c0fc87cce..0f4ccf4c1b 100644 --- a/libraries/testing/contracts.hpp.in +++ b/libraries/testing/contracts.hpp.in @@ -68,6 +68,8 @@ namespace eosio { MAKE_READ_WASM_ABI(params_test, params_test, test-contracts) MAKE_READ_WASM_ABI(crypto_primitives_test,crypto_primitives_test,test-contracts) MAKE_READ_WASM_ABI(get_block_num_test, get_block_num_test, test-contracts) + MAKE_READ_WASM_ABI(nested_container_multi_index, nested_container_multi_index, test-contracts) + }; } /// eosio::testing } /// eosio diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 3f088c0d3b..cf471385fd 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -67,6 +67,9 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/nodeos_contrl_c_test.py ${CMAKE_CURRE configure_file(${CMAKE_CURRENT_SOURCE_DIR}/resource_monitor_plugin_test.py ${CMAKE_CURRENT_BINARY_DIR}/resource_monitor_plugin_test.py COPYONLY) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/light_validation_sync_test.py ${CMAKE_CURRENT_BINARY_DIR}/light_validation_sync_test.py COPYONLY) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/trace_plugin_test.py ${CMAKE_CURRENT_BINARY_DIR}/trace_plugin_test.py COPYONLY) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/nested_container_multi_index_test.py ${CMAKE_CURRENT_BINARY_DIR}/nested_container_multi_index_test.py COPYONLY) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/large-lib-test.py ${CMAKE_CURRENT_BINARY_DIR}/large-lib-test.py COPYONLY) + #To run plugin_test with all log from blockchain displayed, put --verbose after --, i.e. plugin_test -- --verbose add_test(NAME plugin_test COMMAND plugin_test --report_level=detailed --color_output) @@ -147,6 +150,53 @@ set_tests_properties(db_modes_test PROPERTIES COST 6000) add_test(NAME release-build-test COMMAND tests/release-build.sh WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) add_test(NAME version-label-test COMMAND tests/version-label.sh "v${VERSION_FULL}" WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) add_test(NAME full-version-label-test COMMAND tests/full-version-label.sh "v${VERSION_FULL}" ${CMAKE_SOURCE_DIR} WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) +<<<<<<< HEAD +======= +add_test(NAME print-build-info-test COMMAND tests/print-build-info.sh ${CMAKE_SOURCE_DIR} WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) +if(NOT EOSIO_REQUIRE_FULL_VALIDATION) + add_test(NAME light_validation_sync_test COMMAND tests/light_validation_sync_test.py -v --clean-run --dump-error-detail WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) + set_property(TEST light_validation_sync_test PROPERTY LABELS nonparallelizable_tests) + add_test(NAME eosio_blocklog_prune_test COMMAND tests/eosio_blocklog_prune_test.py -v --clean-run --dump-error-detail WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) + set_property(TEST eosio_blocklog_prune_test PROPERTY LABELS nonparallelizable_tests) +endif() +add_test(NAME privacy_startup_network COMMAND tests/privacy_startup_network.py -p 2 -v --clean-run --dump-error-detail WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) +set_property(TEST privacy_startup_network PROPERTY LABELS nonparallelizable_tests) +add_test(NAME privacy_simple_network COMMAND tests/privacy_simple_network.py -p 2 -n 3 -v --clean-run --dump-error-detail WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) +set_property(TEST privacy_simple_network PROPERTY LABELS nonparallelizable_tests) +add_test(NAME privacy_tls_test COMMAND tests/privacy_tls_test.py -v --dump-error-detail WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) +set_property(TEST privacy_tls_test PROPERTY LABELS nonparallelizable_tests) +add_test(NAME privacy_scenario_3_test COMMAND tests/privacy_scenario_3_test.py -v --dump-error-detail WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) +set_property(TEST privacy_scenario_3_test PROPERTY LABELS nonparallelizable_tests) +add_test(NAME privacy_forked_network COMMAND tests/privacy_forked_network.py -p 4 -v --dump-error-detail WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) +set_property(TEST privacy_forked_network PROPERTY LABELS nonparallelizable_tests) +add_test(NAME privacy_config_test_activate COMMAND tests/privacy_config_test_activate.py -v --dump-error-detail WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) +set_property(TEST privacy_config_test_activate PROPERTY LABELS nonparallelizable_tests) +add_test(NAME privacy_config_test_restart COMMAND tests/privacy_config_test_restart.py -v --dump-error-detail WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) +set_property(TEST privacy_config_test_restart PROPERTY LABELS nonparallelizable_tests) +add_test(NAME privacy_config_test_snapshot COMMAND tests/privacy_config_test_snapshot.py -v --dump-error-detail WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) +set_property(TEST privacy_config_test_snapshot PROPERTY LABELS nonparallelizable_tests) +add_test(NAME privacy_config_test_no_ca COMMAND tests/privacy_config_test_no_ca.py -v --dump-error-detail WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) +set_property(TEST privacy_config_test_no_ca PROPERTY LABELS nonparallelizable_tests) +add_test(NAME privacy_network_from_snapshot COMMAND tests/privacy_network_from_snapshot.py -v --dump-error-detail WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) +set_property(TEST privacy_network_from_snapshot PROPERTY LABELS nonparallelizable_tests) +add_test(NAME read_only_query COMMAND tests/read_only_query_tests.py -p 1 -v --dump-error-detail WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) +set_property(TEST read_only_query PROPERTY LABELS nonparallelizable_tests) +add_test(NAME cleos_action_no_params COMMAND tests/cleos_action_no_params.py WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) +set_property(TEST cleos_action_no_params PROPERTY LABELS nonparallelizable_tests) +add_test(NAME nested_container_kv_test COMMAND tests/nested_container_kv_test.py WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) +set_property(TEST nested_container_kv_test PROPERTY LABELS nonparallelizable_tests) +add_test(NAME nested_container_multi_index_test COMMAND tests/nested_container_multi_index_test.py WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) +set_property(TEST nested_container_multi_index_test PROPERTY LABELS nonparallelizable_tests) + +if (ENABLE_RODEOS) + add_test(NAME rodeos_test COMMAND tests/rodeos_test.py -v --clean-run --dump-error-detail WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) + set_property(TEST rodeos_test PROPERTY LABELS nonparallelizable_tests) + if("eos-vm-oc" IN_LIST EOSIO_WASM_RUNTIMES) + add_test(NAME rodeos_test_eosvmoc COMMAND tests/rodeos_test.py -v --clean-run --dump-error-detail --eos-vm-oc-enable WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) + set_property(TEST rodeos_test_eosvmoc PROPERTY LABELS nonparallelizable_tests) + endif() +endif() +>>>>>>> da5b3c0ca... Merge pull request #10635 from EOSIO/nested_container_support_set_optional # Long running tests add_test(NAME nodeos_sanity_lr_test COMMAND tests/nodeos_run_test.py -v --sanity-test --clean-run --dump-error-detail WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) diff --git a/tests/nested_container_kv_test.py b/tests/nested_container_kv_test.py new file mode 100755 index 0000000000..14a6e88045 --- /dev/null +++ b/tests/nested_container_kv_test.py @@ -0,0 +1,392 @@ +#!/usr/bin/env python3 + +from testUtils import Account +from testUtils import Utils +from testUtils import ReturnType +from Cluster import Cluster +from WalletMgr import WalletMgr +from TestHelper import TestHelper +import json + +############################################################### +# Nested_container_kv_test +# +# Load nested container contracts for kv table +# Verifies nested container for table below +# +############################################################### +# | set | vector | optional | map | pair | tuple | +#--------------------------------------------------------------- +#set | X | X | X | X | X | X | +#--------------------------------------------------------------- +#vector | X | X | X | X | X | X | +#--------------------------------------------------------------- +#optional | X | X | X | X | X | X | +#--------------------------------------------------------------- +#map | X | X | X | X | X | X | +#--------------------------------------------------------------- +#pair | X | X | X | X | X | X | +#--------------------------------------------------------------- +#tuple | X | X | X | X | X | X | +#--------------------------------------------------------------- +################################################################ + +Print=Utils.Print +errorExit=Utils.errorExit + +args=TestHelper.parse_args({"-p","-n","-d","-s","--nodes-file","--seed" + ,"--dump-error-details","-v","--leave-running" + ,"--clean-run","--keep-logs"}) + +pnodes=args.p +topo=args.s +delay=args.d +total_nodes = pnodes if args.n < pnodes else args.n +debug=args.v +nodesFile=args.nodes_file +dontLaunch=nodesFile is not None +seed=args.seed +dontKill=args.leave_running +dumpErrorDetails=args.dump_error_details +killAll=args.clean_run +keepLogs=args.keep_logs + +killWallet=not dontKill +killEosInstances=not dontKill +if nodesFile is not None: + killEosInstances=False + +Utils.Debug=debug +testSuccessful=False + +cluster=Cluster(walletd=True) + +walletMgr=WalletMgr(True) +EOSIO_ACCT_PRIVATE_DEFAULT_KEY = "5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3" +EOSIO_ACCT_PUBLIC_DEFAULT_KEY = "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" +contractDir='unittests/test-contracts/nested_container_kv' +wasmFile='nested_container_kv.wasm' +abiFile='nested_container_kv.abi' +kvcontractDir='unittests/contracts' +kvWasmFile='kv_bios.wasm' +kvAbiFile='kv_bios.abi' + +def create_action(action, data, contract_account, usr): + cmdArr= [Utils.EosClientPath, '-v', 'push', 'action', contract_account, action, data, '-p', usr+'@active'] + clargs = node.eosClientArgs().split() + for x in clargs[::-1]: + cmdArr.insert(1, x) + result = Utils.checkOutput(cmdArr, ignoreError=False) + Print("result= ", result) + +try: + cluster.killall(allInstances=False) + cluster.cleanup() + + Print ("producing nodes: %s, non-producing nodes: %d, topology: %s, delay between nodes launch(seconds): %d" % + (pnodes, total_nodes-pnodes, topo, delay)) + + Print("Stand up cluster") + if cluster.launch(pnodes=1, totalNodes=1) is False: + errorExit("Failed to stand up eos cluster.") + + Print ("Wait for Cluster stabilization") + # wait for cluster to start producing blocks + if not cluster.waitOnClusterBlockNumSync(3): + errorExit("Cluster never stabilized") + + Print("Creating kv account") + kvacct = Account('nestcontn2kv') + kvacct.ownerPublicKey = EOSIO_ACCT_PUBLIC_DEFAULT_KEY + kvacct.activePublicKey = EOSIO_ACCT_PUBLIC_DEFAULT_KEY + cluster.createAccountAndVerify(kvacct, cluster.eosioAccount, buyRAM=7000000) + Print("Creating user account") + useracct = Account('alice') + useracct.ownerPublicKey = EOSIO_ACCT_PUBLIC_DEFAULT_KEY + useracct.activePublicKey = EOSIO_ACCT_PUBLIC_DEFAULT_KEY + cluster.createAccountAndVerify(useracct, cluster.eosioAccount, buyRAM=7000000) + + Print("Validating accounts") + cluster.validateAccounts([kvacct, useracct]) + + node = cluster.getNode() + + Print("Setting kv settings account privileged") + node.pushMessage(cluster.eosioAccount.name, 'setpriv', '["nestcontn2kv", 1]', '-p eosio@active') + node.publishContract(cluster.eosioAccount, kvcontractDir, kvWasmFile, kvAbiFile, waitForTransBlock=True) + node.pushMessage(cluster.eosioAccount.name, 'ramkvlimits', '[2024, 2024, 2024]', '-p eosio@active') + + Print("Loading nested container kv contract") + node.publishContract(kvacct, contractDir, wasmFile, abiFile, waitForTransBlock=True) + + Print("Test action for set< set< uint16_t >>") + create_action('setstst', '[1, [[10, 10], [3], [400, 500, 600]]]', 'nestcontn2kv', 'alice') + + Print("Test action for set< vector< uint16_t >>") + create_action('setstv', '[1, [[16, 26], [36], [36], [46, 506, 606]]]', 'nestcontn2kv', 'alice') + + Print("Test action for set< optional< uint16_t >>") + create_action('setsto', '[1, [null, null, 500]]', 'nestcontn2kv', 'alice') + + Print("Test action for set< map< uint16_t, uint16_t >>") + create_action('setstm', '[1, [[{"key":30,"value":300},{"key":30,"value":300}],[{"key":60,"value":600},{"key":60,"value":600}]]]', 'nestcontn2kv', 'alice') + + Print("Test action for set< pair< uint16_t, uint16_t >>") + create_action('setstp', '[1, [{"key": 69, "value": 129}, {"key": 69, "value": 129}]]', 'nestcontn2kv', 'alice') + + Print("Test action for set< tuple< uint16_t, uint16_t >>") + create_action('setstt', '[1, [[1,2],[36,46], [56,66]]]', 'nestcontn2kv', 'alice') + + + Print("Test action for vector< set< uint16_t >>") + create_action('setvst', '[1, [[10, 10], [3], [400, 500, 600]]]', 'nestcontn2kv', 'alice') + + Print("Test action for vector< vector< uint16_t >>") + create_action('setvv', '[1, [[16, 26], [36], [36], [46, 506, 606]]]', 'nestcontn2kv', 'alice') + + Print("Test action for vector< optional< uint16_t >>") + create_action('setvo', '[1,[null, null, 500]]', 'nestcontn2kv', 'alice') + + Print("Test action for vector< map< uint16_t, uint16_t >>") + create_action('setvm', '[1, [[{"key": 30, "value": 300}, {"key": 30, "value": 300}], [{"key": 60, "value": 600}, {"key": 60, "value": 600}]]]' + , 'nestcontn2kv', 'alice') + + Print("Test action for vector< pair< uint16_t, uint16_t >>") + create_action('setvp', '[1, [{"key": 69, "value": 129}, {"key": 69, "value": 129}]]', 'nestcontn2kv', 'alice') + + Print("Test action for vector< tuple< uint16_t, uint16_t >>") + create_action('setvt', '[1, [[10,20],[30,40], [50,60]]]', 'nestcontn2kv', 'alice') + + + Print("Test action for optional< set< uint16_t >>") + create_action('setost', '[1, [10, 10, 3]]', 'nestcontn2kv', 'alice') + create_action('setost', '[2, null]', 'nestcontn2kv', 'alice') + + Print("Test action for optional< vector< uint16_t >>") + create_action('setov', '[1, [46, 506, 606]]', 'nestcontn2kv', 'alice') + create_action('setov', '[2, null]', 'nestcontn2kv', 'alice') + + Print("Test action for optional< optional< uint16_t >>") + create_action('setoo', '[1, 500]', 'nestcontn2kv', 'alice') + create_action('setoo', '[2, null]', 'nestcontn2kv', 'alice') + + Print("Test action for optional< map< uint16_t, uint16_t >>") + create_action('setom', '[1, [{"key": 10, "value": 1000}, {"key": 11,"value": 1001}] ]', 'nestcontn2kv', 'alice') + create_action('setom', '[2, null]', 'nestcontn2kv', 'alice') + + Print("Test action for optional< pair< uint16_t, uint16_t >>") + create_action('setop', '[1, {"key": 60, "value": 61}]', 'nestcontn2kv', 'alice') + create_action('setop', '[2, null]', 'nestcontn2kv', 'alice') + + Print("Test action for optional< tuple< uint16_t, uint16_t >>") + create_action('setot', '[1, [1001,2001]]', 'nestcontn2kv', 'alice') + create_action('setot', '[2, null]', 'nestcontn2kv', 'alice') + + + Print("Test action for map< set< uint16_t >>") + create_action('setmst', '[1, [{"key": 1,"value": [10, 10, 12, 16]}, {"key": 2, "value": [200, 300]} ]]', 'nestcontn2kv', 'alice') + + Print("Test action for map< vector< uint16_t >>") + create_action('setmv', '[1, [{"key": 1, "value": [10, 10, 12, 16]}, {"key": 2, "value": [200, 300]} ]]', 'nestcontn2kv', 'alice') + + Print("Test action for map< optional< uint16_t >>") + create_action('setmo', '[1, [{"key": 10, "value": 1000}, {"key": 11, "value": null}]]', 'nestcontn2kv', 'alice') + + Print("Test action for map< map< uint16_t, uint16_t >>") + create_action('setmm', '[1, [{"key": 10, "value": [{"key": 200, "value": 2000}, \ + {"key": 201, "value": 2001}] }, {"key": 11, "value": [{"key": 300, "value": 3000}, {"key": 301, "value": 3001}] } ]]', 'nestcontn2kv', 'alice') + + Print("Test action for map< pair< uint16_t, uint16_t >>") + create_action('setmp', '[1, [{"key": 36, "value": {"key": 300, "value": 301}}, {"key": 37, "value": {"key": 600, "value": 601}} ]]', 'nestcontn2kv', 'alice') + + Print("Test action for map< tuple< uint16_t, uint16_t >>") + create_action('setmt', '[1, [{"key":1,"value":[10,11]}, {"key":2,"value":[200,300]} ]]', 'nestcontn2kv', 'alice') + + + Print("Test action for pair< set< uint16_t >>") + create_action('setpst', '[1, {"key": 20, "value": [200, 200, 202]}]', 'nestcontn2kv', 'alice') + + Print("Test action for pair< vector< uint16_t >>") + create_action('setpv', '[1, {"key": 10, "value": [100, 100, 102]}]', 'nestcontn2kv', 'alice') + + Print("Test action for pair< optional< uint16_t >>") + create_action('setpo', '[1, {"key": 70, "value": 71}]', 'nestcontn2kv', 'alice') + create_action('setpo', '[2, {"key": 70, "value": null}]', 'nestcontn2kv', 'alice') + + Print("Test action for pair< map< uint16_t, uint16_t >>") + create_action('setpm', '[1, {"key": 6, "value": [{"key": 20, "value": 300}, {"key": 21,"value": 301}] }]', 'nestcontn2kv', 'alice') + + Print("Test action for pair< pair< uint16_t, uint16_t >>") + create_action('setpp', '[1, {"key": 30, "value": {"key": 301, "value": 302} }]', 'nestcontn2kv', 'alice') + + Print("Test action for pair< tuple< uint16_t, uint16_t >>") + create_action('setpt', '[1, {"key":10, "value":[100,101]}]', 'nestcontn2kv', 'alice') + + + Print("Test action for tuple< uint16_t, set< uint16_t >, set< uint16_t >>") + create_action('settst', '[1, [10,[21,31], [41,51,61]]]', 'nestcontn2kv', 'alice') + + Print("Test action for tuple< uint16_t, vector< uint16_t >, vector< uint16_t >") + create_action('settv', '[1, [16,[26,36], [46,506,606]]]', 'nestcontn2kv', 'alice') + + Print("Test action for tuple< optional< uint16_t >, optional< uint16_t >, optional< uint16_t > \ + , optional< uint16_t >, optional< uint16_t >>") + create_action('setto', '[1, [100, null, 200, null, 300]]', 'nestcontn2kv', 'alice') + create_action('setto', '[2, [null, null, 10, null, 20]]', 'nestcontn2kv', 'alice') + + Print("Test action for tuple< map< uint16_t, uint16_t >, map< uint16_t, uint16_t >>") + create_action('settm', '[1, [126, [{"key":10,"value":100},{"key":11,"value":101}], [{"key":80,"value":800},{"key":81,"value":9009}] ]]', 'nestcontn2kv', 'alice') + + Print("Test action for tuple< uint16_t, pair< uint16_t, uint16_t >, pair< uint16_t, uint16_t >>") + create_action('settp', '[1, [127, {"key":18, "value":28}, {"key":19, "value":29}]]', 'nestcontn2kv', 'alice') + + Print("Test action for tuple< tuple< uint16_t, uint16_t >, tuple< uint16_t, uint16_t >, tuple< uint16_t, uint16_t >>") + create_action('settt', '[1, [[1,2],[30,40], [50,60]]]', 'nestcontn2kv', 'alice') + + + Print("Test action for vector>") + create_action('setvos', '[1, [{"_count": 18, "_strID": "dumstr"}, null, {"_count": 19, "_strID": "dumstr"}]]', 'nestcontn2kv', 'alice') + + Print("Test action for pair>>") + create_action('setpvo', '[1,{"first": 183, "second":[100, null, 200]}]', 'nestcontn2kv', 'alice') + + cmd="get kv_table %s people2kv map.index" % kvacct.name + transaction = node.processCleosCmd(cmd, cmd, False, returnType=ReturnType.raw) + transaction_json = json.loads(transaction) + + assert "[[3], [10], [400, 500, 600]]" == str(transaction_json['rows'][0]['stst']), \ + 'Content of kv table set< set< uint16_t >> is not correct' + + assert "[[16, 26], [36], [46, 506, 606]]" == str(transaction_json['rows'][0]['stv']), \ + 'Content of kv table set< vector< uint16_t >> is not correct' + + assert "[None, 500]" == str(transaction_json['rows'][0]['sto']), 'Content of kv table set< optional< uint16_t >> is not correct' + + assert "[[{'key': 30, 'value': 300}], [{'key': 60, 'value': 600}]]" \ + == str(transaction_json['rows'][0]['stm']), 'Content of kv table set< map< uint16_t >> is not correct' + + assert "[{'key': 69, 'value': 129}]" == str(transaction_json['rows'][0]['stp']), \ + 'Content of kv table set< pair< uint16_t >> is not correct' + + assert "[{'field_0': 1, 'field_1': 2}, {'field_0': 36, 'field_1': 46}, {'field_0': 56, 'field_1': 66}]" == str(transaction_json['rows'][0]['stt']), \ + 'Content of kv table set< tuple< uint16_t, uint16_t >> is not correct' + + + + assert "[[10], [3], [400, 500, 600]]" == str(transaction_json['rows'][0]['vst']), \ + 'Content of kv table vector< set< uint16_t >> is not correct' + + assert "[[16, 26], [36], [36], [46, 506, 606]]" == str(transaction_json['rows'][0]['vv']), \ + 'Content of kv table vector< vector< uint16_t >> is not correct' + + assert "[None, None, 500]" == str(transaction_json['rows'][0]['vo']), \ + 'Content of kv table vector< optional< uint16_t >> is not correct' + + assert "[[{'key': 30, 'value': 300}], [{'key': 60, 'value': 600}]]" \ + == str(transaction_json['rows'][0]['vm']), 'Content of kv table vector< map< uint16_t >> is not correct' + + assert "[{'key': 69, 'value': 129}, {'key': 69, 'value': 129}]" == str(transaction_json['rows'][0]['vp']), \ + 'Content of kv table vector< pair< uint16_t >> is not correct' + + assert "[{'field_0': 10, 'field_1': 20}, {'field_0': 30, 'field_1': 40}, {'field_0': 50, 'field_1': 60}]" == str(transaction_json['rows'][0]['vt']), \ + 'Content of kv table vector< tuple< uint16_t, uint16_t >> is not correct' + + + assert "[3, 10]" == str(transaction_json['rows'][0]['ost']), 'Content of kv table optional< set< uint16_t >> is not correct' + assert "None" == str(transaction_json['rows'][1]['ost']), 'Content of kv table optional< set< uint16_t >> is not correct' + + assert "[46, 506, 606]" == str(transaction_json['rows'][0]['ov']), 'Content of kv table optional< vector< uint16_t >> is not correct' + assert "None" == str(transaction_json['rows'][1]['ov']), 'Content of kv table optional< set< uint16_t >> is not correct' + + assert "500" == str(transaction_json['rows'][0]['oo']), 'Content of kv table optional< optional< uint16_t >> is not correct' + assert "None" == str(transaction_json['rows'][1]['oo']), 'Content of kv table optional< set< uint16_t >> is not correct' + + assert "[{'key': 10, 'value': 1000}, {'key': 11, 'value': 1001}]" \ + == str(transaction_json['rows'][0]['om']), 'Content of kv table optional< map< uint16_t >> is not correct' + assert "None" == str(transaction_json['rows'][1]['om']), 'Content of kv table optional< set< uint16_t >> is not correct' + + assert "{'key': 60, 'value': 61}" == str(transaction_json['rows'][0]['op']), \ + 'Content of kv table optional< pair< uint16_t >> is not correct' + assert "None" == str(transaction_json['rows'][1]['op']), 'Content of kv table optional< set< uint16_t >> is not correct' + + assert "{'field_0': 1001, 'field_1': 2001}" == str(transaction_json['rows'][0]['ot']), 'Content of kv table optional< tuple< uint16_t, uint16_t >> is not correct' + assert "None" == str(transaction_json['rows'][1]['ot']), 'Content of kv table optional< tuple< uint16_t, uint16_t >> is not correct' + + + assert "[{'key': 1, 'value': [10, 12, 16]}, {'key': 2, 'value': [200, 300]}]" \ + == str(transaction_json['rows'][0]['mst']), 'Content of kv table map< set< uint16_t >> is not correct' + + assert "[{'key': 1, 'value': [10, 10, 12, 16]}, {'key': 2, 'value': [200, 300]}]" \ + == str(transaction_json['rows'][0]['mv']), 'Content of kv table map< vector< uint16_t >> is not correct' + + assert "[{'key': 10, 'value': 1000}, {'key': 11, 'value': None}]" == \ + str(transaction_json['rows'][0]['mo']), 'Content of kv table map< optional< uint16_t >> is not correct' + + assert "[{'key': 10, 'value': [{'key': 200, 'value': 2000}, {'key': 201, 'value': 2001}]}, {'key': 11, 'value': [{'key': 300, 'value': 3000}, {'key': 301, 'value': 3001}]}]" \ + == str(transaction_json['rows'][0]['mm']), 'Content of kv table map< map< uint16_t >> is not correct' + + assert "[{'key': 36, 'value': {'key': 300, 'value': 301}}, {'key': 37, 'value': {'key': 600, 'value': 601}}]"\ + == str(transaction_json['rows'][0]['mp']), 'Content of kv table map< pair< uint16_t >> is not correct' + + assert "[{'key': 1, 'value': {'field_0': 10, 'field_1': 11}}, {'key': 2, 'value': {'field_0': 200, 'field_1': 300}}]"\ + == str(transaction_json['rows'][0]['mt']), 'Content of kv table map< uint16_t, tuple< uint16_t, uint16_t >> is not correct' + + + assert "{'key': 20, 'value': [200, 202]}" == str(transaction_json['rows'][0]['pst']), \ + 'Content of kv table pair< set< uint16_t >> is not correct' + + assert "{'key': 10, 'value': [100, 100, 102]}" == str(transaction_json['rows'][0]['pv']), \ + 'Content of kv table pair< vector< uint16_t >> is not correct' + + assert "{'key': 70, 'value': 71}" == str(transaction_json['rows'][0]['po']), \ + 'Content of kv table pair< optional< uint16_t >> is not correct' + + assert "{'key': 70, 'value': None}" == str(transaction_json['rows'][1]['po']), \ + 'Content of kv table pair< optional< uint16_t >> is not correct' + + assert "{'key': 6, 'value': [{'key': 20, 'value': 300}, {'key': 21, 'value': 301}]}" \ + == str(transaction_json['rows'][0]['pm']), 'Content of kv table pair< map< uint16_t >> is not correct' + + assert "{'key': 30, 'value': {'key': 301, 'value': 302}}" == str(transaction_json['rows'][0]['pp']),\ + 'Content of kv table pair< pair< uint16_t >> is not correct' + + assert "{'key': 10, 'value': {'field_0': 100, 'field_1': 101}}"\ + == str(transaction_json['rows'][0]['pt']), 'Content of kv table pair< uint16_t, tuple< uint16_t, uint16_t >> is not correct' + + + assert "{'field_0': 10, 'field_1': [21, 31], 'field_2': [41, 51, 61]}" == str(transaction_json['rows'][0]['tst']), \ + 'Content of kv table tuple< set< uint16_t >> is not correct' + + assert "{'field_0': 16, 'field_1': [26, 36], 'field_2': [46, 506, 606]}" == str(transaction_json['rows'][0]['tv']), \ + 'Content of kv table tuple< vector< uint16_t >> is not correct' + + assert "{'field_0': 100, 'field_1': None, 'field_2': 200, 'field_3': None, 'field_4': 300}" == str(transaction_json['rows'][0]['to']), \ + 'Content of kv table tuple< optional< uint16_t >> is not correct' + + assert "{'field_0': None, 'field_1': None, 'field_2': 10, 'field_3': None, 'field_4': 20}" == str(transaction_json['rows'][1]['to']), \ + 'Content of kv table tuple< optional< uint16_t >> is not correct' + + assert "{'field_0': 126, 'field_1': [{'key': 10, 'value': 100}, {'key': 11, 'value': 101}], 'field_2': [{'key': 80, 'value': 800}, {'key': 81, 'value': 9009}]}" \ + == str(transaction_json['rows'][0]['tm']), 'Content of kv table pair< map< uint16_t, uint16_t >> is not correct' + + assert "{'field_0': 127, 'field_1': {'key': 18, 'value': 28}, 'field_2': {'key': 19, 'value': 29}}" == str(transaction_json['rows'][0]['tp']),\ + 'Content of kv table tuple< pair< uint16_t, uint16_t >> is not correct' + + assert "{'field_0': {'field_0': 1, 'field_1': 2}, 'field_1': {'field_0': 30, 'field_1': 40}, 'field_2': {'field_0': 50, 'field_1': 60}}"\ + == str(transaction_json['rows'][0]['tt']), 'Content of kv table tuple< tuple< uint16_t, uint16_t >, ...> is not correct' + + + assert "[{'_count': 18, '_strID': 'dumstr'}, None, {'_count': 19, '_strID': 'dumstr'}]" == str(transaction_json['rows'][0]['vos']), \ + "Content of kv table vector> is not correct" + + assert "{'first': 183, 'second': [100, None, 200]}" == str(transaction_json['rows'][0]['pvo']), \ + "Content of kv table pair>> is not correct" + + testSuccessful=True + + assert testSuccessful + +finally: + TestHelper.shutdown(cluster, walletMgr, testSuccessful, killEosInstances, killWallet) + +exit(0) \ No newline at end of file diff --git a/tests/nested_container_multi_index_test.py b/tests/nested_container_multi_index_test.py new file mode 100755 index 0000000000..ccc4f027e5 --- /dev/null +++ b/tests/nested_container_multi_index_test.py @@ -0,0 +1,393 @@ +#!/usr/bin/env python3 + +from testUtils import Account +from testUtils import Utils +from testUtils import ReturnType +from Cluster import Cluster +from WalletMgr import WalletMgr +from TestHelper import TestHelper +import json + +############################################################### +# Nested_container_multi_index_test +# +# Load nested container contracts for multi-index table +# Verifies nested container for table below +# +############################################################### +# | set | vector | optional | map | pair | tuple | +#--------------------------------------------------------------- +#set | X | X | X | X | X | X | +#--------------------------------------------------------------- +#vector | X | X | X | X | X | X | +#--------------------------------------------------------------- +#optional | X | X | X | X | X | X | +#--------------------------------------------------------------- +#map | X | X | X | X | X | X | +#--------------------------------------------------------------- +#pair | X | X | X | X | X | X | +#--------------------------------------------------------------- +#tuple | X | X | X | X | X | X | +#--------------------------------------------------------------- +################################################################ + +Print=Utils.Print +errorExit=Utils.errorExit + +args=TestHelper.parse_args({"-p","-n","-d","-s","--nodes-file","--seed" + ,"--dump-error-details","-v","--leave-running" + ,"--clean-run","--keep-logs"}) + +pnodes=args.p +topo=args.s +delay=args.d +total_nodes = pnodes if args.n < pnodes else args.n +debug=args.v +nodesFile=args.nodes_file +dontLaunch=nodesFile is not None +seed=args.seed +dontKill=args.leave_running +dumpErrorDetails=args.dump_error_details +killAll=args.clean_run +keepLogs=args.keep_logs + +killWallet=not dontKill +killEosInstances=not dontKill +if nodesFile is not None: + killEosInstances=False + +Utils.Debug=debug +testSuccessful=False + +cluster=Cluster(walletd=True) + +walletMgr=WalletMgr(True) +EOSIO_ACCT_PRIVATE_DEFAULT_KEY = "5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3" +EOSIO_ACCT_PUBLIC_DEFAULT_KEY = "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" +contractDir='unittests/test-contracts/nested_container_multi_index' +wasmFile='nested_container_multi_index.wasm' +abiFile='nested_container_multi_index.abi' + +def create_action(action, data, contract_account, usr): + cmdArr= [Utils.EosClientPath, '-v', 'push', 'action', contract_account, action, data, '-p', usr+'@active'] + clargs = node.eosClientArgs().split() + for x in clargs[::-1]: + cmdArr.insert(1, x) + result = Utils.checkOutput(cmdArr, ignoreError=False) + Print("result= ", result) + +try: + cluster.killall(allInstances=False) + cluster.cleanup() + + Print ("producing nodes: %s, non-producing nodes: %d, topology: %s, delay between nodes launch(seconds): %d" % + (pnodes, total_nodes-pnodes, topo, delay)) + + Print("Stand up cluster") + if cluster.launch(pnodes=1, totalNodes=1) is False: + errorExit("Failed to stand up eos cluster.") + + Print ("Wait for Cluster stabilization") + # wait for cluster to start producing blocks + if not cluster.waitOnClusterBlockNumSync(3): + errorExit("Cluster never stabilized") + + Print("Creating multi_index account") + MIacct = Account('nestcontnmi') + MIacct.ownerPublicKey = EOSIO_ACCT_PUBLIC_DEFAULT_KEY + MIacct.activePublicKey = EOSIO_ACCT_PUBLIC_DEFAULT_KEY + cluster.createAccountAndVerify(MIacct, cluster.eosioAccount, buyRAM=7000000) + Print("Creating user account alice") + useracct_I = Account('alice') + useracct_I.ownerPublicKey = EOSIO_ACCT_PUBLIC_DEFAULT_KEY + useracct_I.activePublicKey = EOSIO_ACCT_PUBLIC_DEFAULT_KEY + cluster.createAccountAndVerify(useracct_I, cluster.eosioAccount, buyRAM=7000000) + + Print("Creating user account bob") + useracct_II = Account('bob') + useracct_II.ownerPublicKey = EOSIO_ACCT_PUBLIC_DEFAULT_KEY + useracct_II.activePublicKey = EOSIO_ACCT_PUBLIC_DEFAULT_KEY + cluster.createAccountAndVerify(useracct_II, cluster.eosioAccount, buyRAM=7000000) + + Print("Validating accounts") + cluster.validateAccounts([MIacct, useracct_I, useracct_II]) + + node = cluster.getNode() + + Print("Setting account privilege") + node.pushMessage(cluster.eosioAccount.name, 'setpriv', '["nestcontnmi", 1]', '-p eosio@active') + + Print("Loading nested container contract") + node.publishContract(MIacct, contractDir, wasmFile, abiFile, waitForTransBlock=True) + + Print("Test action for set< set< uint16_t >>") + create_action('setstst', '["alice", [[10, 10], [3], [400, 500, 600]]]', 'nestcontnmi', 'alice') + + Print("Test action for set< vector< uint16_t >>") + create_action('setstv', '["alice", [[16, 26], [36], [36], [46, 506, 606]]]', 'nestcontnmi', 'alice') + + Print("Test action for set< optional< uint16_t >>") + create_action('setsto', '["alice", [null, null, 500]]', 'nestcontnmi', 'alice') + + Print("Test action for set< map< uint16_t, uint16_t >>") + create_action('setstm', '["alice", [[{"key":30,"value":300},{"key":30,"value":300}],[{"key":60,"value":600},{"key":60,"value":600}]]]', 'nestcontnmi', 'alice') + + Print("Test action for set< pair< uint16_t, uint16_t >>") + create_action('setstp', '["alice", [{"key": 69, "value": 129}, {"key": 69, "value": 129}]]', 'nestcontnmi', 'alice') + + Print("Test action for set< tuple< uint16_t, uint16_t >>") + create_action('setstt', '["alice", [[1,2],[36,46], [56,66]]]', 'nestcontnmi', 'alice') + + + Print("Test action for vector< set< uint16_t >>") + create_action('setvst', '["alice", [[10, 10], [3], [400, 500, 600]]]', 'nestcontnmi', 'alice') + + Print("Test action for vector< vector< uint16_t >>") + create_action('setvv', '["alice", [[16, 26], [36], [36], [46, 506, 606]]]', 'nestcontnmi', 'alice') + + Print("Test action for vector< optional< uint16_t >>") + create_action('setvo', '["alice",[null, null, 500]]', 'nestcontnmi', 'alice') + + Print("Test action for vector< map< uint16_t, uint16_t >>") + create_action('setvm', '["alice", [[{"key": 30, "value": 300}, {"key": 30, "value": 300}], [{"key": 60, "value": 600}, {"key": 60, "value": 600}]]]' + , 'nestcontnmi', 'alice') + + Print("Test action for vector< pair< uint16_t, uint16_t >>") + create_action('setvp', '["alice", [{"key": 69, "value": 129}, {"key": 69, "value": 129}]]', 'nestcontnmi', 'alice') + + Print("Test action for vector< tuple< uint16_t, uint16_t >>") + create_action('setvt', '["alice", [[10,20],[30,40], [50,60]]]', 'nestcontnmi', 'alice') + + + Print("Test action for optional< set< uint16_t >>") + create_action('setost', '["alice", [10, 10, 3]]', 'nestcontnmi', 'alice') + create_action('setost', '["bob", null]', 'nestcontnmi', 'bob') + + Print("Test action for optional< vector< uint16_t >>") + create_action('setov', '["alice", [46, 506, 606]]', 'nestcontnmi', 'alice') + create_action('setov', '["bob", null]', 'nestcontnmi', 'bob') + + Print("Test action for optional< optional< uint16_t >>") + create_action('setoo', '["alice", 500]', 'nestcontnmi', 'alice') + create_action('setoo', '["bob", null]', 'nestcontnmi', 'bob') + + Print("Test action for optional< map< uint16_t, uint16_t >>") + create_action('setom', '["alice", [{"key": 10, "value": 1000}, {"key": 11,"value": 1001}] ]', 'nestcontnmi', 'alice') + create_action('setom', '["bob", null]', 'nestcontnmi', 'bob') + + Print("Test action for optional< pair< uint16_t, uint16_t >>") + create_action('setop', '["alice", {"key": 60, "value": 61}]', 'nestcontnmi', 'alice') + create_action('setop', '["bob", null]', 'nestcontnmi', 'bob') + + Print("Test action for optional< tuple< uint16_t, uint16_t >>") + create_action('setot', '["alice", [1001,2001]]', 'nestcontnmi', 'alice') + create_action('setot', '["bob", null]', 'nestcontnmi', 'bob') + + + Print("Test action for map< set< uint16_t >>") + create_action('setmst', '["alice", [{"key": 1,"value": [10, 10, 12, 16]}, {"key": 2, "value": [200, 300]} ]]', 'nestcontnmi', 'alice') + + Print("Test action for map< vector< uint16_t >>") + create_action('setmv', '["alice", [{"key": 1, "value": [10, 10, 12, 16]}, {"key": 2, "value": [200, 300]} ]]', 'nestcontnmi', 'alice') + + Print("Test action for map< optional< uint16_t >>") + create_action('setmo', '["alice", [{"key": 10, "value": 1000}, {"key": 11, "value": null}]]', 'nestcontnmi', 'alice') + + Print("Test action for map< map< uint16_t, uint16_t >>") + create_action('setmm', '["alice", [{"key": 10, "value": [{"key": 200, "value": 2000}, \ + {"key": 201, "value": 2001}] }, {"key": 11, "value": [{"key": 300, "value": 3000}, {"key": 301, "value": 3001}] } ]]', 'nestcontnmi', 'alice') + + Print("Test action for map< pair< uint16_t, uint16_t >>") + create_action('setmp', '["alice", [{"key": 36, "value": {"key": 300, "value": 301}}, {"key": 37, "value": {"key": 600, "value": 601}} ]]', 'nestcontnmi', 'alice') + + Print("Test action for map< tuple< uint16_t, uint16_t >>") + create_action('setmt', '["alice", [{"key":1,"value":[10,11]}, {"key":2,"value":[200,300]} ]]', 'nestcontnmi', 'alice') + + + Print("Test action for pair< set< uint16_t >>") + create_action('setpst', '["alice", {"key": 20, "value": [200, 200, 202]}]', 'nestcontnmi', 'alice') + + Print("Test action for pair< vector< uint16_t >>") + create_action('setpv', '["alice", {"key": 10, "value": [100, 100, 102]}]', 'nestcontnmi', 'alice') + + Print("Test action for pair< optional< uint16_t >>") + create_action('setpo', '["alice", {"key": 70, "value": 71}]', 'nestcontnmi', 'alice') + create_action('setpo', '["bob", {"key": 70, "value": null}]', 'nestcontnmi', 'bob') + + Print("Test action for pair< map< uint16_t, uint16_t >>") + create_action('setpm', '["alice", {"key": 6, "value": [{"key": 20, "value": 300}, {"key": 21,"value": 301}] }]', 'nestcontnmi', 'alice') + + Print("Test action for pair< pair< uint16_t, uint16_t >>") + create_action('setpp', '["alice", {"key": 30, "value": {"key": 301, "value": 302} }]', 'nestcontnmi', 'alice') + + Print("Test action for pair< tuple< uint16_t, uint16_t >>") + create_action('setpt', '["alice", {"key":10, "value":[100,101]}]', 'nestcontnmi', 'alice') + + + Print("Test action for tuple< uint16_t, set< uint16_t >, set< uint16_t >>") + create_action('settst', '["alice", [10,[21,31], [41,51,61]]]', 'nestcontnmi', 'alice') + + Print("Test action for tuple< uint16_t, vector< uint16_t >, vector< uint16_t >") + create_action('settv', '["alice", [16,[26,36], [46,506,606]]]', 'nestcontnmi', 'alice') + + Print("Test action for tuple< optional< uint16_t >, optional< uint16_t >, optional< uint16_t > \ + , optional< uint16_t >, optional< uint16_t >>") + create_action('setto', '["alice", [100, null, 200, null, 300]]', 'nestcontnmi', 'alice') + create_action('setto', '["bob", [null, null, 10, null, 20]]', 'nestcontnmi', 'bob') + + Print("Test action for tuple< map< uint16_t, uint16_t >, map< uint16_t, uint16_t >>") + create_action('settm', '["alice", [126, [{"key":10,"value":100},{"key":11,"value":101}], [{"key":80,"value":800},{"key":81,"value":9009}] ]]', 'nestcontnmi', 'alice') + + Print("Test action for tuple< uint16_t, pair< uint16_t, uint16_t >, pair< uint16_t, uint16_t >>") + create_action('settp', '["alice", [127, {"key":18, "value":28}, {"key":19, "value":29}]]', 'nestcontnmi', 'alice') + + Print("Test action for tuple< tuple< uint16_t, uint16_t >, tuple< uint16_t, uint16_t >, tuple< uint16_t, uint16_t >>") + create_action('settt', '["alice", [[1,2],[30,40], [50,60]]]', 'nestcontnmi', 'alice') + + + Print("Test action for vector>") + create_action('setvos', '["alice", [{"_count": 18, "_strID": "dumstr"}, null, {"_count": 19, "_strID": "dumstr"}]]', 'nestcontnmi', 'alice') + + Print("Test action for pair>>") + create_action('setpvo', '["alice",{"first": 183, "second":[100, null, 200]}]', 'nestcontnmi', 'alice') + + cmd="get table %s %s people2" % (MIacct.name, MIacct.name) + + transaction = node.processCleosCmd(cmd, cmd, False, returnType=ReturnType.raw) + transaction_json = json.loads(transaction) + + assert "[[3], [10], [400, 500, 600]]" == str(transaction_json['rows'][0]['stst']), \ + 'Content of multi-index table set< set< uint16_t >> is not correct' + + assert "[[16, 26], [36], [46, 506, 606]]" == str(transaction_json['rows'][0]['stv']), \ + 'Content of multi-index table set< vector< uint16_t >> is not correct' + + assert "[None, 500]" == str(transaction_json['rows'][0]['sto']), 'Content of multi-index table set< optional< uint16_t >> is not correct' + + assert "[[{'key': 30, 'value': 300}], [{'key': 60, 'value': 600}]]" \ + == str(transaction_json['rows'][0]['stm']), 'Content of multi-index table set< map< uint16_t >> is not correct' + + assert "[{'key': 69, 'value': 129}]" == str(transaction_json['rows'][0]['stp']), \ + 'Content of multi-index table set< pair< uint16_t >> is not correct' + + assert "[{'field_0': 1, 'field_1': 2}, {'field_0': 36, 'field_1': 46}, {'field_0': 56, 'field_1': 66}]" == str(transaction_json['rows'][0]['stt']), \ + 'Content of multi-index table set< tuple< uint16_t, uint16_t >> is not correct' + + + + assert "[[10], [3], [400, 500, 600]]" == str(transaction_json['rows'][0]['vst']), \ + 'Content of multi-index table vector< set< uint16_t >> is not correct' + + assert "[[16, 26], [36], [36], [46, 506, 606]]" == str(transaction_json['rows'][0]['vv']), \ + 'Content of multi-index table vector< vector< uint16_t >> is not correct' + + assert "[None, None, 500]" == str(transaction_json['rows'][0]['vo']), \ + 'Content of multi-index table vector< optional< uint16_t >> is not correct' + + assert "[[{'key': 30, 'value': 300}], [{'key': 60, 'value': 600}]]" \ + == str(transaction_json['rows'][0]['vm']), 'Content of multi-index table vector< map< uint16_t >> is not correct' + + assert "[{'key': 69, 'value': 129}, {'key': 69, 'value': 129}]" == str(transaction_json['rows'][0]['vp']), \ + 'Content of multi-index table vector< pair< uint16_t >> is not correct' + + assert "[{'field_0': 10, 'field_1': 20}, {'field_0': 30, 'field_1': 40}, {'field_0': 50, 'field_1': 60}]" == str(transaction_json['rows'][0]['vt']), \ + 'Content of multi-index table vector< tuple< uint16_t, uint16_t >> is not correct' + + + assert "[3, 10]" == str(transaction_json['rows'][0]['ost']), 'Content of multi-index table optional< set< uint16_t >> is not correct' + assert "None" == str(transaction_json['rows'][1]['ost']), 'Content of multi-index table optional< set< uint16_t >> is not correct' + + assert "[46, 506, 606]" == str(transaction_json['rows'][0]['ov']), 'Content of multi-index table optional< vector< uint16_t >> is not correct' + assert "None" == str(transaction_json['rows'][1]['ov']), 'Content of multi-index table optional< set< uint16_t >> is not correct' + + assert "500" == str(transaction_json['rows'][0]['oo']), 'Content of multi-index table optional< optional< uint16_t >> is not correct' + assert "None" == str(transaction_json['rows'][1]['oo']), 'Content of multi-index table optional< set< uint16_t >> is not correct' + + assert "[{'key': 10, 'value': 1000}, {'key': 11, 'value': 1001}]" \ + == str(transaction_json['rows'][0]['om']), 'Content of multi-index table optional< map< uint16_t >> is not correct' + assert "None" == str(transaction_json['rows'][1]['om']), 'Content of multi-index table optional< set< uint16_t >> is not correct' + + assert "{'key': 60, 'value': 61}" == str(transaction_json['rows'][0]['op']), \ + 'Content of multi-index table optional< pair< uint16_t >> is not correct' + assert "None" == str(transaction_json['rows'][1]['op']), 'Content of multi-index table optional< set< uint16_t >> is not correct' + + assert "{'field_0': 1001, 'field_1': 2001}" == str(transaction_json['rows'][0]['ot']), 'Content of multi-index table optional< tuple< uint16_t, uint16_t >> is not correct' + assert "None" == str(transaction_json['rows'][1]['ot']), 'Content of multi-index table optional< tuple< uint16_t, uint16_t >> is not correct' + + + assert "[{'key': 1, 'value': [10, 12, 16]}, {'key': 2, 'value': [200, 300]}]" \ + == str(transaction_json['rows'][0]['mst']), 'Content of multi-index table map< set< uint16_t >> is not correct' + + assert "[{'key': 1, 'value': [10, 10, 12, 16]}, {'key': 2, 'value': [200, 300]}]" \ + == str(transaction_json['rows'][0]['mv']), 'Content of multi-index table map< vector< uint16_t >> is not correct' + + assert "[{'key': 10, 'value': 1000}, {'key': 11, 'value': None}]" == \ + str(transaction_json['rows'][0]['mo']), 'Content of multi-index table map< optional< uint16_t >> is not correct' + + assert "[{'key': 10, 'value': [{'key': 200, 'value': 2000}, {'key': 201, 'value': 2001}]}, {'key': 11, 'value': [{'key': 300, 'value': 3000}, {'key': 301, 'value': 3001}]}]" \ + == str(transaction_json['rows'][0]['mm']), 'Content of multi-index table map< map< uint16_t >> is not correct' + + assert "[{'key': 36, 'value': {'key': 300, 'value': 301}}, {'key': 37, 'value': {'key': 600, 'value': 601}}]"\ + == str(transaction_json['rows'][0]['mp']), 'Content of multi-index table map< pair< uint16_t >> is not correct' + + assert "[{'key': 1, 'value': {'field_0': 10, 'field_1': 11}}, {'key': 2, 'value': {'field_0': 200, 'field_1': 300}}]"\ + == str(transaction_json['rows'][0]['mt']), 'Content of multi-index table map< uint16_t, tuple< uint16_t, uint16_t >> is not correct' + + + assert "{'key': 20, 'value': [200, 202]}" == str(transaction_json['rows'][0]['pst']), \ + 'Content of multi-index table pair< set< uint16_t >> is not correct' + + assert "{'key': 10, 'value': [100, 100, 102]}" == str(transaction_json['rows'][0]['pv']), \ + 'Content of multi-index table pair< vector< uint16_t >> is not correct' + + assert "{'key': 70, 'value': 71}" == str(transaction_json['rows'][0]['po']), \ + 'Content of multi-index table pair< optional< uint16_t >> is not correct' + + assert "{'key': 70, 'value': None}" == str(transaction_json['rows'][1]['po']), \ + 'Content of multi-index table pair< optional< uint16_t >> is not correct' + + assert "{'key': 6, 'value': [{'key': 20, 'value': 300}, {'key': 21, 'value': 301}]}" \ + == str(transaction_json['rows'][0]['pm']), 'Content of multi-index table pair< map< uint16_t >> is not correct' + + assert "{'key': 30, 'value': {'key': 301, 'value': 302}}" == str(transaction_json['rows'][0]['pp']),\ + 'Content of multi-index table pair< pair< uint16_t >> is not correct' + + assert "{'key': 10, 'value': {'field_0': 100, 'field_1': 101}}"\ + == str(transaction_json['rows'][0]['pt']), 'Content of multi-index table pair< uint16_t, tuple< uint16_t, uint16_t >> is not correct' + + + assert "{'field_0': 10, 'field_1': [21, 31], 'field_2': [41, 51, 61]}" == str(transaction_json['rows'][0]['tst']), \ + 'Content of multi-index table tuple< set< uint16_t >> is not correct' + + assert "{'field_0': 16, 'field_1': [26, 36], 'field_2': [46, 506, 606]}" == str(transaction_json['rows'][0]['tv']), \ + 'Content of multi-index table tuple< vector< uint16_t >> is not correct' + + assert "{'field_0': 100, 'field_1': None, 'field_2': 200, 'field_3': None, 'field_4': 300}" == str(transaction_json['rows'][0]['to']), \ + 'Content of multi-index table tuple< optional< uint16_t >> is not correct' + + assert "{'field_0': None, 'field_1': None, 'field_2': 10, 'field_3': None, 'field_4': 20}" == str(transaction_json['rows'][1]['to']), \ + 'Content of multi-index table tuple< optional< uint16_t >> is not correct' + + assert "{'field_0': 126, 'field_1': [{'key': 10, 'value': 100}, {'key': 11, 'value': 101}], 'field_2': [{'key': 80, 'value': 800}, {'key': 81, 'value': 9009}]}" \ + == str(transaction_json['rows'][0]['tm']), 'Content of multi-index table pair< map< uint16_t, uint16_t >> is not correct' + + assert "{'field_0': 127, 'field_1': {'key': 18, 'value': 28}, 'field_2': {'key': 19, 'value': 29}}" == str(transaction_json['rows'][0]['tp']),\ + 'Content of multi-index table tuple< pair< uint16_t, uint16_t >> is not correct' + + assert "{'field_0': {'field_0': 1, 'field_1': 2}, 'field_1': {'field_0': 30, 'field_1': 40}, 'field_2': {'field_0': 50, 'field_1': 60}}"\ + == str(transaction_json['rows'][0]['tt']), 'Content of multi-index table tuple< tuple< uint16_t, uint16_t >, ...> is not correct' + + + assert "[{'_count': 18, '_strID': 'dumstr'}, None, {'_count': 19, '_strID': 'dumstr'}]" == str(transaction_json['rows'][0]['vos']), \ + "Content of multi-index table vector> is not correct" + + assert "{'first': 183, 'second': [100, None, 200]}" == str(transaction_json['rows'][0]['pvo']), \ + "Content of multi-index table pair>> is not correct" + + testSuccessful=True + assert testSuccessful + +finally: + TestHelper.shutdown(cluster, walletMgr, testSuccessful, killEosInstances, killWallet) + +exit(0) \ No newline at end of file diff --git a/unittests/abi_tests.cpp b/unittests/abi_tests.cpp index 3d0c719c26..6ad37bd994 100644 --- a/unittests/abi_tests.cpp +++ b/unittests/abi_tests.cpp @@ -2812,8 +2812,13 @@ BOOST_AUTO_TEST_CASE(abi_deserialize_detailed_error_messages) ], })"; + // Some details here: c::variant("030101000103") represents an array of std::optional {1,null,3}, and + // fc::variant("0400000000") represents an array of 4 nulls. Also fc::variant("030001af013a") represents {null, 0xAF, 0x3A}. + // Test to verify that array of optinal doesn't throw exception + abi_serializer abis( fc::json::from_string(abi).as(), abi_serializer::create_yield_function( max_serialization_time ) ); + BOOST_CHECK_NO_THROW( abis.binary_to_variant("s4", fc::variant("030101000103").as(), abi_serializer::create_yield_function( max_serialization_time )) ); + try { - abi_serializer abis( fc::json::from_string(abi).as(), abi_serializer::create_yield_function( max_serialization_time ) ); BOOST_CHECK_EXCEPTION( abis.binary_to_variant("s2", fc::variant("020102").as(), abi_serializer::create_yield_function( max_serialization_time )), unpack_exception, fc_exception_message_is("Stream unexpectedly ended; unable to unpack field 'f1' of struct 's2'") ); @@ -2830,12 +2835,6 @@ BOOST_AUTO_TEST_CASE(abi_deserialize_detailed_error_messages) BOOST_CHECK_EXCEPTION( abis.binary_to_variant("s3", fc::variant("02010304").as(), abi_serializer::create_yield_function( max_serialization_time )), abi_exception, fc_exception_message_is("Encountered field 'i5' without binary extension designation while processing struct 's3'") ); - // This check actually points to a problem with the current abi_serializer. - // An array of optionals (which is unfortunately not rejected in validation) leads to an unpack_exception here because one of the optional elements is not present. - // However, abis.binary_to_variant("s4", fc::variant("03010101020103").as(), max_serialization_time) would work just fine! - BOOST_CHECK_EXCEPTION( abis.binary_to_variant("s4", fc::variant("030101000103").as(), abi_serializer::create_yield_function( max_serialization_time )), - unpack_exception, fc_exception_message_is("Invalid packed array 's4.f0[1]'") ); - BOOST_CHECK_EXCEPTION( abis.binary_to_variant("s4", fc::variant("020101").as(), abi_serializer::create_yield_function( max_serialization_time )), unpack_exception, fc_exception_message_is("Unable to unpack optional of built-in type 'int8' while processing 's4.f0[1]'") ); diff --git a/unittests/test-contracts/CMakeLists.txt b/unittests/test-contracts/CMakeLists.txt index 7a78722b89..c5d32bfa18 100644 --- a/unittests/test-contracts/CMakeLists.txt +++ b/unittests/test-contracts/CMakeLists.txt @@ -39,3 +39,6 @@ add_subdirectory( wasm_config_bios ) add_subdirectory( params_test ) add_subdirectory( crypto_primitives_test ) add_subdirectory( get_block_num_test ) +add_subdirectory( security_group_test ) +add_subdirectory( nested_container_kv ) +add_subdirectory( nested_container_multi_index ) diff --git a/unittests/test-contracts/nested_container_kv/CMakeLists.txt b/unittests/test-contracts/nested_container_kv/CMakeLists.txt new file mode 100644 index 0000000000..36cc1a1f90 --- /dev/null +++ b/unittests/test-contracts/nested_container_kv/CMakeLists.txt @@ -0,0 +1,6 @@ +if( EOSIO_COMPILE_TEST_CONTRACTS ) + add_contract( nested_container_kv nested_container_kv nested_container_kv.cpp ) +else() + configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/nested_container_kv.wasm ${CMAKE_CURRENT_BINARY_DIR}/nested_container_kv.wasm COPYONLY ) + configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/nested_container_kv.abi ${CMAKE_CURRENT_BINARY_DIR}/nested_container_kv.abi COPYONLY ) +endif() \ No newline at end of file diff --git a/unittests/test-contracts/nested_container_kv/nested_container_kv.abi b/unittests/test-contracts/nested_container_kv/nested_container_kv.abi new file mode 100644 index 0000000000..7ca29d0719 --- /dev/null +++ b/unittests/test-contracts/nested_container_kv/nested_container_kv.abi @@ -0,0 +1,1212 @@ +{ + "____comment": "This file was generated with eosio-abigen. DO NOT EDIT ", + "version": "eosio::abi/1.2", + "types": [ + { + "new_type_name": "mp_uint16", + "type": "pair_uint16_uint16[]" + }, + { + "new_type_name": "op_struc", + "type": "mystruct?" + }, + { + "new_type_name": "op_uint16", + "type": "uint16?" + }, + { + "new_type_name": "pr_uint16", + "type": "pair_uint16_uint16" + }, + { + "new_type_name": "set_uint16", + "type": "uint16[]" + }, + { + "new_type_name": "tup_uint16", + "type": "tuple_uint16_uint16" + }, + { + "new_type_name": "vec_op_uint16", + "type": "op_uint16[]" + }, + { + "new_type_name": "vec_uint16", + "type": "uint16[]" + } + ], + "structs": [ + { + "name": "get", + "base": "", + "fields": [ + { + "name": "id", + "type": "int32" + } + ] + }, + { + "name": "mystruct", + "base": "", + "fields": [ + { + "name": "_count", + "type": "uint64" + }, + { + "name": "_strID", + "type": "string" + } + ] + }, + { + "name": "pair_uint16_mp_uint16", + "base": "", + "fields": [ + { + "name": "key", + "type": "uint16" + }, + { + "name": "value", + "type": "mp_uint16" + } + ] + }, + { + "name": "pair_uint16_op_uint16", + "base": "", + "fields": [ + { + "name": "key", + "type": "uint16" + }, + { + "name": "value", + "type": "op_uint16" + } + ] + }, + { + "name": "pair_uint16_pr_uint16", + "base": "", + "fields": [ + { + "name": "key", + "type": "uint16" + }, + { + "name": "value", + "type": "pr_uint16" + } + ] + }, + { + "name": "pair_uint16_set_uint16", + "base": "", + "fields": [ + { + "name": "key", + "type": "uint16" + }, + { + "name": "value", + "type": "set_uint16" + } + ] + }, + { + "name": "pair_uint16_tup_uint16", + "base": "", + "fields": [ + { + "name": "key", + "type": "uint16" + }, + { + "name": "value", + "type": "tup_uint16" + } + ] + }, + { + "name": "pair_uint16_uint16", + "base": "", + "fields": [ + { + "name": "key", + "type": "uint16" + }, + { + "name": "value", + "type": "uint16" + } + ] + }, + { + "name": "pair_uint16_vec_op_uint16", + "base": "", + "fields": [ + { + "name": "first", + "type": "uint16" + }, + { + "name": "second", + "type": "vec_op_uint16" + } + ] + }, + { + "name": "pair_uint16_vec_uint16", + "base": "", + "fields": [ + { + "name": "key", + "type": "uint16" + }, + { + "name": "value", + "type": "vec_uint16" + } + ] + }, + { + "name": "person2kv", + "base": "", + "fields": [ + { + "name": "stst", + "type": "set_uint16[]" + }, + { + "name": "stv", + "type": "vec_uint16[]" + }, + { + "name": "sto", + "type": "op_uint16[]" + }, + { + "name": "stm", + "type": "mp_uint16[]" + }, + { + "name": "stp", + "type": "pr_uint16[]" + }, + { + "name": "stt", + "type": "tup_uint16[]" + }, + { + "name": "vst", + "type": "set_uint16[]" + }, + { + "name": "vv", + "type": "vec_uint16[]" + }, + { + "name": "vo", + "type": "op_uint16[]" + }, + { + "name": "vm", + "type": "mp_uint16[]" + }, + { + "name": "vp", + "type": "pr_uint16[]" + }, + { + "name": "vt", + "type": "tup_uint16[]" + }, + { + "name": "ost", + "type": "set_uint16?" + }, + { + "name": "ov", + "type": "vec_uint16?" + }, + { + "name": "oo", + "type": "op_uint16?" + }, + { + "name": "om", + "type": "mp_uint16?" + }, + { + "name": "op", + "type": "pr_uint16?" + }, + { + "name": "ot", + "type": "tup_uint16?" + }, + { + "name": "mst", + "type": "pair_uint16_set_uint16[]" + }, + { + "name": "mv", + "type": "pair_uint16_vec_uint16[]" + }, + { + "name": "mo", + "type": "pair_uint16_op_uint16[]" + }, + { + "name": "mm", + "type": "pair_uint16_mp_uint16[]" + }, + { + "name": "mp", + "type": "pair_uint16_pr_uint16[]" + }, + { + "name": "mt", + "type": "pair_uint16_tup_uint16[]" + }, + { + "name": "pst", + "type": "pair_uint16_set_uint16" + }, + { + "name": "pv", + "type": "pair_uint16_vec_uint16" + }, + { + "name": "po", + "type": "pair_uint16_op_uint16" + }, + { + "name": "pm", + "type": "pair_uint16_mp_uint16" + }, + { + "name": "pp", + "type": "pair_uint16_pr_uint16" + }, + { + "name": "pt", + "type": "pair_uint16_tup_uint16" + }, + { + "name": "tv", + "type": "tuple_uint16_vec_uint16_vec_uint16" + }, + { + "name": "tst", + "type": "tuple_uint16_set_uint16_set_uint16" + }, + { + "name": "to", + "type": "tuple_op_uint16_op_uint16_op_uint16_op_uint16_op_uint16" + }, + { + "name": "tm", + "type": "tuple_uint16_mp_uint16_mp_uint16" + }, + { + "name": "tp", + "type": "tuple_uint16_pr_uint16_pr_uint16" + }, + { + "name": "tt", + "type": "tuple_tup_uint16_tup_uint16_tup_uint16" + }, + { + "name": "vos", + "type": "op_struc[]" + }, + { + "name": "pvo", + "type": "pair_uint16_vec_op_uint16" + } + ] + }, + { + "name": "setmm", + "base": "", + "fields": [ + { + "name": "id", + "type": "int32" + }, + { + "name": "mm", + "type": "pair_uint16_mp_uint16[]" + } + ] + }, + { + "name": "setmo", + "base": "", + "fields": [ + { + "name": "id", + "type": "int32" + }, + { + "name": "mo", + "type": "pair_uint16_op_uint16[]" + } + ] + }, + { + "name": "setmp", + "base": "", + "fields": [ + { + "name": "id", + "type": "int32" + }, + { + "name": "mp", + "type": "pair_uint16_pr_uint16[]" + } + ] + }, + { + "name": "setmst", + "base": "", + "fields": [ + { + "name": "id", + "type": "int32" + }, + { + "name": "mst", + "type": "pair_uint16_set_uint16[]" + } + ] + }, + { + "name": "setmt", + "base": "", + "fields": [ + { + "name": "id", + "type": "int32" + }, + { + "name": "mt", + "type": "pair_uint16_tup_uint16[]" + } + ] + }, + { + "name": "setmv", + "base": "", + "fields": [ + { + "name": "id", + "type": "int32" + }, + { + "name": "mv", + "type": "pair_uint16_vec_uint16[]" + } + ] + }, + { + "name": "setom", + "base": "", + "fields": [ + { + "name": "id", + "type": "int32" + }, + { + "name": "om", + "type": "mp_uint16?" + } + ] + }, + { + "name": "setoo", + "base": "", + "fields": [ + { + "name": "id", + "type": "int32" + }, + { + "name": "oo", + "type": "op_uint16?" + } + ] + }, + { + "name": "setop", + "base": "", + "fields": [ + { + "name": "id", + "type": "int32" + }, + { + "name": "op", + "type": "pr_uint16?" + } + ] + }, + { + "name": "setost", + "base": "", + "fields": [ + { + "name": "id", + "type": "int32" + }, + { + "name": "ost", + "type": "set_uint16?" + } + ] + }, + { + "name": "setot", + "base": "", + "fields": [ + { + "name": "id", + "type": "int32" + }, + { + "name": "ot", + "type": "tup_uint16?" + } + ] + }, + { + "name": "setov", + "base": "", + "fields": [ + { + "name": "id", + "type": "int32" + }, + { + "name": "ov", + "type": "vec_uint16?" + } + ] + }, + { + "name": "setpm", + "base": "", + "fields": [ + { + "name": "id", + "type": "int32" + }, + { + "name": "pm", + "type": "pair_uint16_mp_uint16" + } + ] + }, + { + "name": "setpo", + "base": "", + "fields": [ + { + "name": "id", + "type": "int32" + }, + { + "name": "po", + "type": "pair_uint16_op_uint16" + } + ] + }, + { + "name": "setpp", + "base": "", + "fields": [ + { + "name": "id", + "type": "int32" + }, + { + "name": "pp", + "type": "pair_uint16_pr_uint16" + } + ] + }, + { + "name": "setpst", + "base": "", + "fields": [ + { + "name": "id", + "type": "int32" + }, + { + "name": "pst", + "type": "pair_uint16_set_uint16" + } + ] + }, + { + "name": "setpt", + "base": "", + "fields": [ + { + "name": "id", + "type": "int32" + }, + { + "name": "pt", + "type": "pair_uint16_tup_uint16" + } + ] + }, + { + "name": "setpv", + "base": "", + "fields": [ + { + "name": "id", + "type": "int32" + }, + { + "name": "pv", + "type": "pair_uint16_vec_uint16" + } + ] + }, + { + "name": "setpvo", + "base": "", + "fields": [ + { + "name": "id", + "type": "int32" + }, + { + "name": "pvo", + "type": "pair_uint16_vec_op_uint16" + } + ] + }, + { + "name": "setstm", + "base": "", + "fields": [ + { + "name": "id", + "type": "int32" + }, + { + "name": "stm", + "type": "mp_uint16[]" + } + ] + }, + { + "name": "setsto", + "base": "", + "fields": [ + { + "name": "id", + "type": "int32" + }, + { + "name": "sto", + "type": "op_uint16[]" + } + ] + }, + { + "name": "setstp", + "base": "", + "fields": [ + { + "name": "id", + "type": "int32" + }, + { + "name": "stp", + "type": "pr_uint16[]" + } + ] + }, + { + "name": "setstst", + "base": "", + "fields": [ + { + "name": "id", + "type": "int32" + }, + { + "name": "stst", + "type": "set_uint16[]" + } + ] + }, + { + "name": "setstt", + "base": "", + "fields": [ + { + "name": "id", + "type": "int32" + }, + { + "name": "stt", + "type": "tup_uint16[]" + } + ] + }, + { + "name": "setstv", + "base": "", + "fields": [ + { + "name": "id", + "type": "int32" + }, + { + "name": "stv", + "type": "vec_uint16[]" + } + ] + }, + { + "name": "settm", + "base": "", + "fields": [ + { + "name": "id", + "type": "int32" + }, + { + "name": "tm", + "type": "tuple_uint16_mp_uint16_mp_uint16" + } + ] + }, + { + "name": "setto", + "base": "", + "fields": [ + { + "name": "id", + "type": "int32" + }, + { + "name": "to", + "type": "tuple_op_uint16_op_uint16_op_uint16_op_uint16_op_uint16" + } + ] + }, + { + "name": "settp", + "base": "", + "fields": [ + { + "name": "id", + "type": "int32" + }, + { + "name": "tp", + "type": "tuple_uint16_pr_uint16_pr_uint16" + } + ] + }, + { + "name": "settst", + "base": "", + "fields": [ + { + "name": "id", + "type": "int32" + }, + { + "name": "tst", + "type": "tuple_uint16_set_uint16_set_uint16" + } + ] + }, + { + "name": "settt", + "base": "", + "fields": [ + { + "name": "id", + "type": "int32" + }, + { + "name": "tt", + "type": "tuple_tup_uint16_tup_uint16_tup_uint16" + } + ] + }, + { + "name": "settv", + "base": "", + "fields": [ + { + "name": "id", + "type": "int32" + }, + { + "name": "tv", + "type": "tuple_uint16_vec_uint16_vec_uint16" + } + ] + }, + { + "name": "setvm", + "base": "", + "fields": [ + { + "name": "id", + "type": "int32" + }, + { + "name": "vm", + "type": "mp_uint16[]" + } + ] + }, + { + "name": "setvo", + "base": "", + "fields": [ + { + "name": "id", + "type": "int32" + }, + { + "name": "vo", + "type": "op_uint16[]" + } + ] + }, + { + "name": "setvos", + "base": "", + "fields": [ + { + "name": "id", + "type": "int32" + }, + { + "name": "vos", + "type": "op_struc[]" + } + ] + }, + { + "name": "setvp", + "base": "", + "fields": [ + { + "name": "id", + "type": "int32" + }, + { + "name": "vp", + "type": "pr_uint16[]" + } + ] + }, + { + "name": "setvst", + "base": "", + "fields": [ + { + "name": "id", + "type": "int32" + }, + { + "name": "vst", + "type": "set_uint16[]" + } + ] + }, + { + "name": "setvt", + "base": "", + "fields": [ + { + "name": "id", + "type": "int32" + }, + { + "name": "vt", + "type": "tup_uint16[]" + } + ] + }, + { + "name": "setvv", + "base": "", + "fields": [ + { + "name": "id", + "type": "int32" + }, + { + "name": "vv", + "type": "vec_uint16[]" + } + ] + }, + { + "name": "tuple_op_uint16_op_uint16_op_uint16_op_uint16_op_uint16", + "base": "", + "fields": [ + { + "name": "field_0", + "type": "op_uint16" + }, + { + "name": "field_1", + "type": "op_uint16" + }, + { + "name": "field_2", + "type": "op_uint16" + }, + { + "name": "field_3", + "type": "op_uint16" + }, + { + "name": "field_4", + "type": "op_uint16" + } + ] + }, + { + "name": "tuple_tup_uint16_tup_uint16_tup_uint16", + "base": "", + "fields": [ + { + "name": "field_0", + "type": "tup_uint16" + }, + { + "name": "field_1", + "type": "tup_uint16" + }, + { + "name": "field_2", + "type": "tup_uint16" + } + ] + }, + { + "name": "tuple_uint16_mp_uint16_mp_uint16", + "base": "", + "fields": [ + { + "name": "field_0", + "type": "uint16" + }, + { + "name": "field_1", + "type": "mp_uint16" + }, + { + "name": "field_2", + "type": "mp_uint16" + } + ] + }, + { + "name": "tuple_uint16_pr_uint16_pr_uint16", + "base": "", + "fields": [ + { + "name": "field_0", + "type": "uint16" + }, + { + "name": "field_1", + "type": "pr_uint16" + }, + { + "name": "field_2", + "type": "pr_uint16" + } + ] + }, + { + "name": "tuple_uint16_set_uint16_set_uint16", + "base": "", + "fields": [ + { + "name": "field_0", + "type": "uint16" + }, + { + "name": "field_1", + "type": "set_uint16" + }, + { + "name": "field_2", + "type": "set_uint16" + } + ] + }, + { + "name": "tuple_uint16_uint16", + "base": "", + "fields": [ + { + "name": "field_0", + "type": "uint16" + }, + { + "name": "field_1", + "type": "uint16" + } + ] + }, + { + "name": "tuple_uint16_vec_uint16_vec_uint16", + "base": "", + "fields": [ + { + "name": "field_0", + "type": "uint16" + }, + { + "name": "field_1", + "type": "vec_uint16" + }, + { + "name": "field_2", + "type": "vec_uint16" + } + ] + } + ], + "actions": [ + { + "name": "get", + "type": "get", + "ricardian_contract": "" + }, + { + "name": "setmm", + "type": "setmm", + "ricardian_contract": "" + }, + { + "name": "setmo", + "type": "setmo", + "ricardian_contract": "" + }, + { + "name": "setmp", + "type": "setmp", + "ricardian_contract": "" + }, + { + "name": "setmst", + "type": "setmst", + "ricardian_contract": "" + }, + { + "name": "setmt", + "type": "setmt", + "ricardian_contract": "" + }, + { + "name": "setmv", + "type": "setmv", + "ricardian_contract": "" + }, + { + "name": "setom", + "type": "setom", + "ricardian_contract": "" + }, + { + "name": "setoo", + "type": "setoo", + "ricardian_contract": "" + }, + { + "name": "setop", + "type": "setop", + "ricardian_contract": "" + }, + { + "name": "setost", + "type": "setost", + "ricardian_contract": "" + }, + { + "name": "setot", + "type": "setot", + "ricardian_contract": "" + }, + { + "name": "setov", + "type": "setov", + "ricardian_contract": "" + }, + { + "name": "setpm", + "type": "setpm", + "ricardian_contract": "" + }, + { + "name": "setpo", + "type": "setpo", + "ricardian_contract": "" + }, + { + "name": "setpp", + "type": "setpp", + "ricardian_contract": "" + }, + { + "name": "setpst", + "type": "setpst", + "ricardian_contract": "" + }, + { + "name": "setpt", + "type": "setpt", + "ricardian_contract": "" + }, + { + "name": "setpv", + "type": "setpv", + "ricardian_contract": "" + }, + { + "name": "setpvo", + "type": "setpvo", + "ricardian_contract": "" + }, + { + "name": "setstm", + "type": "setstm", + "ricardian_contract": "" + }, + { + "name": "setsto", + "type": "setsto", + "ricardian_contract": "" + }, + { + "name": "setstp", + "type": "setstp", + "ricardian_contract": "" + }, + { + "name": "setstst", + "type": "setstst", + "ricardian_contract": "" + }, + { + "name": "setstt", + "type": "setstt", + "ricardian_contract": "" + }, + { + "name": "setstv", + "type": "setstv", + "ricardian_contract": "" + }, + { + "name": "settm", + "type": "settm", + "ricardian_contract": "" + }, + { + "name": "setto", + "type": "setto", + "ricardian_contract": "" + }, + { + "name": "settp", + "type": "settp", + "ricardian_contract": "" + }, + { + "name": "settst", + "type": "settst", + "ricardian_contract": "" + }, + { + "name": "settt", + "type": "settt", + "ricardian_contract": "" + }, + { + "name": "settv", + "type": "settv", + "ricardian_contract": "" + }, + { + "name": "setvm", + "type": "setvm", + "ricardian_contract": "" + }, + { + "name": "setvo", + "type": "setvo", + "ricardian_contract": "" + }, + { + "name": "setvos", + "type": "setvos", + "ricardian_contract": "" + }, + { + "name": "setvp", + "type": "setvp", + "ricardian_contract": "" + }, + { + "name": "setvst", + "type": "setvst", + "ricardian_contract": "" + }, + { + "name": "setvt", + "type": "setvt", + "ricardian_contract": "" + }, + { + "name": "setvv", + "type": "setvv", + "ricardian_contract": "" + } + ], + "tables": [], + "kv_tables": { + "people2kv": { + "type": "person2kv", + "primary_index": { + "name": "map.index", + "type": "int32" + }, + "secondary_indices": {} + } + }, + "ricardian_clauses": [], + "variants": [], + "action_results": [ + { + "name": "get", + "result_type": "person2kv" + } + ] +} \ No newline at end of file diff --git a/unittests/test-contracts/nested_container_kv/nested_container_kv.cpp b/unittests/test-contracts/nested_container_kv/nested_container_kv.cpp new file mode 100644 index 0000000000..f51661949e --- /dev/null +++ b/unittests/test-contracts/nested_container_kv/nested_container_kv.cpp @@ -0,0 +1,402 @@ +/* Verify the support of nested containers for the new Key-value table eosio::kv::map + * For each action, an example regarding how to use the action with the cleos command line is given. + * + * std:pair is a struct with 2 fields first and second, + * std::map is handled as an array/vector of pairs/structs by EOSIO with implicit fields key, value, + * the cases of combined use of key/value and first/second involving map,pair in the cleos are documented here, + * so handling of std::pair is NOT the same as the handling of a general struct such as struct mystruct! + * + * When assigning data input with cleos: + * [] represents an empty vector/set or empty map where T, T1, T2 can be any composite types + * null represents an uninitialized std::optional where T can be any composite type + * BUT [] or null can NOT be used to represent an empty struct or empty std::pair + * + * Attention: + * 1) Please follow https://github.com/EOSIO/eos/tree/develop/contracts/enable-kv to enable key-value support of nodeos first + * 2) To get to the point right away, here authentication/permission checking is skipped for each action in this contract, + * however in practice, suitable permission checking such as require_auth(user) has to be used! + * + */ + +#include +#include + +#include +#include +#include +#include +#include + +using namespace eosio; +using namespace std; + + +#define SETCONTAINERVAL(x) do { \ + person2kv obj = mymap[id]; \ + obj.x = x; \ + mymap[id] = obj; \ + }while(0) + +struct mystruct +{ + uint64_t _count; + string _strID; +}; + +typedef set set_uint16; +typedef vector vec_uint16; +typedef optional op_uint16; +typedef map mp_uint16; +typedef pair pr_uint16; + +typedef vector< op_uint16 > vec_op_uint16; +typedef optional< mystruct > op_struc; +typedef tuple tup_uint16; + +struct person2kv { + set< set_uint16 > stst; + set< vec_uint16 > stv; + set< op_uint16 > sto; + set< mp_uint16 > stm; + set< pr_uint16 > stp; + set< tup_uint16 > stt; + + vector< set_uint16 > vst; + vector< vec_uint16 > vv; + vector< op_uint16 > vo; + vector< mp_uint16 > vm; + vector< pr_uint16 > vp; + vector< tup_uint16 > vt; + + optional< set_uint16 > ost; + optional< vec_uint16 > ov; + optional< op_uint16 > oo; + optional< mp_uint16 > om; + optional< pr_uint16 > op; + optional< tup_uint16 > ot; + + map< uint16_t, set_uint16 > mst; + map< uint16_t, vec_uint16 > mv; + map< uint16_t, op_uint16 > mo; + map< uint16_t, mp_uint16 > mm; + map< uint16_t, pr_uint16 > mp; + map< uint16_t, tup_uint16 > mt; + + pair< uint16_t, set_uint16 > pst; + pair< uint16_t, vec_uint16 > pv; + pair< uint16_t, op_uint16 > po; + pair< uint16_t, mp_uint16 > pm; + pair< uint16_t, pr_uint16 > pp; + pair< uint16_t, tup_uint16 > pt; + + tuple< uint16_t, vec_uint16, vec_uint16 > tv; + tuple< uint16_t, set_uint16, set_uint16 > tst; + tuple< op_uint16, op_uint16, op_uint16,op_uint16,op_uint16 > to; + tuple< uint16_t, mp_uint16, mp_uint16 > tm; + tuple< uint16_t, pr_uint16, pr_uint16 > tp; + tuple< tup_uint16, tup_uint16, tup_uint16 > tt; + + vector< op_struc > vos; + pair< uint16_t, vec_op_uint16 > pvo; +}; + +class [[eosio::contract("nested_container_kv")]] nestcontn2kv : public eosio::contract { + using my_map_t = eosio::kv::map<"people2kv"_n, int, person2kv>; + + private: + my_map_t mymap{}; + + public: + using contract::contract; + + nestcontn2kv(name receiver, name code, datastream ds): contract(receiver, code, ds) {} + + [[eosio::action]] + person2kv get(int id){ + //This action will be used by all prntx actions to retrieve item_found for given id + auto iter = mymap.find(id); + check(iter != mymap.end(), "Record does not exist"); + const auto& item_found = iter->second(); + return item_found; + } + + [[eosio::action]] + void setstst(int id, const set< set_uint16 >& stst){ + SETCONTAINERVAL(stst); + eosio::print("type defined set< set< uint16_t >> stored successfully!"); + } + + [[eosio::action]] + void setstv(int id, const set< vec_uint16 >& stv){ + SETCONTAINERVAL(stv); + eosio::print("type defined set< vector< uint16_t >> stored successfully!"); + } + + [[eosio::action]] + void setsto(int id, const set< op_uint16 >& sto){ + SETCONTAINERVAL(sto); + eosio::print("type defined set< optional< uint16_t >> stored successfully!"); + } + + [[eosio::action]] + void setstm(int id, const set< mp_uint16 >& stm){ + SETCONTAINERVAL(stm); + eosio::print("type defined set< map< uint16_t, uint16_t>> stored successfully!"); + } + + [[eosio::action]] + void setstp(int id, const set< pr_uint16 >& stp){ + SETCONTAINERVAL(stp); + eosio::print("type defined set< pair< uint16_t, uint16_t >> stored successfully"); + } + + [[eosio::action]] + void setstt(int id, const set< tup_uint16 >& stt){ + SETCONTAINERVAL(stt); + eosio::print("type defined set< tuple< uint16_t, uint16_t >> stored successfully!"); + } + + + [[eosio::action]] + void setvst(int id, const vector< set_uint16 >& vst){ + SETCONTAINERVAL(vst); + eosio::print("type defined vector< set< uint16_t >> stored successfully!"); + } + + [[eosio::action]] + void setvv(int id, const vector< vec_uint16 >& vv){ + SETCONTAINERVAL(vv); + eosio::print("type defined vector< vector< uint16_t >> stored successfully!"); + } + + [[eosio::action]] + void setvo(int id, const vector< op_uint16 >& vo){ + SETCONTAINERVAL(vo); + eosio::print("type defined vector< optional< uint16_t >> stored successfully!"); + } + + [[eosio::action]] + void setvm(int id, const vector< mp_uint16 >& vm){ + SETCONTAINERVAL(vm); + eosio::print("type defined vector< map< uint16_t, uint16_t>> stored successfully!"); + } + + [[eosio::action]] + void setvp(int id, const vector< pr_uint16 >& vp){ + SETCONTAINERVAL(vp); + eosio::print("type defined vector< pair< uint16_t, uint16_t >> stored successfully"); + } + + [[eosio::action]] + void setvt(int id, const vector& vt){ + SETCONTAINERVAL(vt); + eosio::print("type defined vector< tuple< uint16_t, uint16_t >> stored successfully!"); + } + + + [[eosio::action]] + void setost(int id, const optional< set_uint16 >& ost){ + SETCONTAINERVAL(ost); + eosio::print("type defined optional< set< uint16_t >> stored successfully!"); + } + + [[eosio::action]] + void setov(int id, const optional< vec_uint16 >& ov){ + SETCONTAINERVAL(ov); + eosio::print("type defined optional< vector< uint16_t >> stored successfully!"); + } + + [[eosio::action]] + void setoo(int id, const optional< op_uint16 > & oo){ + SETCONTAINERVAL(oo); + eosio::print("type defined optional< optional< uint16_t >> stored successfully!"); + } + + [[eosio::action]] + void setom(int id, const optional< mp_uint16 >& om){ + SETCONTAINERVAL(om); + eosio::print("type defined optional< map< uint16_t, uint16_t>> stored successfully!"); + } + + [[eosio::action]] + void setop(int id, const optional< pr_uint16 >& op){ + SETCONTAINERVAL(op); + eosio::print("type defined optional< pair< uint16_t, uint16_t >> stored successfully"); + } + + [[eosio::action]] + void setot(int id, const optional& ot){ + SETCONTAINERVAL(ot); + eosio::print("type defined optional< tuple< uint16_t, uint16_t >> stored successfully!"); + } + + [[eosio::action]] + void setmst(int id, const map< uint16_t, set_uint16 >& mst){ + SETCONTAINERVAL(mst); + eosio::print("type defined map< set< uint16_t >> stored successfully!"); + } + + [[eosio::action]] + void setmv(int id, const map< uint16_t, vec_uint16 >& mv){ + SETCONTAINERVAL(mv); + eosio::print("type defined map< vector< uint16_t >> stored successfully!"); + } + + [[eosio::action]] + void setmo(int id, const map< uint16_t, op_uint16 > & mo){ + SETCONTAINERVAL(mo); + eosio::print("type defined map< optional< uint16_t >> stored successfully!"); + } + + [[eosio::action]] + void setmm(int id, const map< uint16_t, mp_uint16 >& mm){ + SETCONTAINERVAL(mm); + eosio::print("type defined map< map< uint16_t, uint16_t >> stored successfully!"); + } + + [[eosio::action]] + void setmp(int id, const map< uint16_t, pr_uint16 >& mp){ + SETCONTAINERVAL(mp); + eosio::print("type defined map< pair< uint16_t, uint16_t >> stored successfully"); + } + + [[eosio::action]] + void setmt(int id, const map& mt){ + SETCONTAINERVAL(mt); + eosio::print("type defined map< uint16_t, tuple< uint16_t, uint16_t >> stored successfully!"); + } + + [[eosio::action]] + void setpst(int id, const pair< uint16_t, set_uint16 >& pst){ + SETCONTAINERVAL(pst); + eosio::print("type defined pair< set< uint16_t >> stored successfully!"); + } + + [[eosio::action]] + void setpv(int id, const pair< uint16_t, vec_uint16 >& pv){ + SETCONTAINERVAL(pv); + eosio::print("type defined pair< vector< uint16_t >> stored successfully!"); + } + + [[eosio::action]] + void setpo(int id, const pair< uint16_t, op_uint16 > & po){ + SETCONTAINERVAL(po); + eosio::print("type defined pair< optional< uint16_t >> stored successfully!"); + } + + [[eosio::action]] + void setpm(int id, const pair< uint16_t, mp_uint16 >& pm){ + SETCONTAINERVAL(pm); + eosio::print("type defined pair< map< uint16_t, uint16_t>> stored successfully!"); + } + + [[eosio::action]] + void setpp(int id, const pair< uint16_t, pr_uint16 >& pp){ + SETCONTAINERVAL(pp); + eosio::print("type defined pair< pair< uint16_t, uint16_t >> stored successfully"); + } + + [[eosio::action]] + void setpt(int id, const pair& pt){ + SETCONTAINERVAL(pt); + eosio::print("type defined pair< uint16_t, tuple< uint16_t, uint16_t >> stored successfully!"); + } + + [[eosio::action]] + void settst(int id, const tuple& tst){ + SETCONTAINERVAL(tst); + eosio::print("type defined tuple< uint16_t, set< uint16_t >, set< uint16_t >> stored successfully!"); + } + + [[eosio::action]] + void settv(int id, const tuple& tv){ + SETCONTAINERVAL(tv); + eosio::print("type defined tuple< uint16_t, vector< uint16_t >, vector< uint16_t > stored successfully!"); + } + + [[eosio::action]] + void setto(int id, const tuple & to){ + SETCONTAINERVAL(to); + eosio::print("type defined tuple< optional < uint16_t >, optional < uint16_t >, ... > stored successfully!"); + } + + [[eosio::action]] + void settm(int id, const tuple& tm){ + SETCONTAINERVAL(tm); + eosio::print("type defined tuple< map< uint16_t, map< uint16_t, uint16_t>, map< uint16_t, uint16_t> >> stored successfully!"); + } + + [[eosio::action]] + void settp(int id, const tuple& tp){ + SETCONTAINERVAL(tp); + eosio::print("type defined tuple< uint16_t, pair< uint16_t, uint16_t >, pair< uint16_t, uint16_t >> stored successfully"); + } + + [[eosio::action]] + void settt(int id, const tuple< tup_uint16, tup_uint16, tup_uint16 >& tt){ + SETCONTAINERVAL(tt); + eosio::print("type defined tuple< tuple< uint16_t, uint16_t >, ... > stored successfully!"); + } + + [[eosio::action]] + void setvos(int id, const vector& vos){ + SETCONTAINERVAL(vos); + eosio::print("vector> stored successfully"); + } + + [[eosio::action]] + void setpvo(int id, const pair& pvo){ + SETCONTAINERVAL(pvo); + eosio::print("pair>> stored successfully"); + } + + using get_action = eosio::action_wrapper<"get"_n, &nestcontn2kv::get>; + + using setstst_action = eosio::action_wrapper<"setstst"_n, &nestcontn2kv::setstst>; + using setstv_action = eosio::action_wrapper<"setstv"_n, &nestcontn2kv::setstv>; + using setsto_action = eosio::action_wrapper<"setsto"_n, &nestcontn2kv::setsto>; + using setstm_action = eosio::action_wrapper<"setstm"_n, &nestcontn2kv::setstm>; + using setstp_action = eosio::action_wrapper<"setstp"_n, &nestcontn2kv::setstp>; + using setstt_action = eosio::action_wrapper<"setstt"_n, &nestcontn2kv::setstt>; + + using setvst_action = eosio::action_wrapper<"setvst"_n, &nestcontn2kv::setvst>; + using setvv_action = eosio::action_wrapper<"setvv"_n, &nestcontn2kv::setvv>; + using setvo_action = eosio::action_wrapper<"setvo"_n, &nestcontn2kv::setvo>; + using setvm_action = eosio::action_wrapper<"setvm"_n, &nestcontn2kv::setvm>; + using setvp_action = eosio::action_wrapper<"setvp"_n, &nestcontn2kv::setvp>; + using setvt_action = eosio::action_wrapper<"setvt"_n, &nestcontn2kv::setvt>; + + using setost_action = eosio::action_wrapper<"setost"_n, &nestcontn2kv::setost>; + using setov_action = eosio::action_wrapper<"setov"_n, &nestcontn2kv::setov>; + using setoo_action = eosio::action_wrapper<"setoo"_n, &nestcontn2kv::setoo>; + using setom_action = eosio::action_wrapper<"setom"_n, &nestcontn2kv::setom>; + using setop_action = eosio::action_wrapper<"setop"_n, &nestcontn2kv::setop>; + using setot_action = eosio::action_wrapper<"setot"_n, &nestcontn2kv::setot>; + + using setmst_action = eosio::action_wrapper<"setmst"_n, &nestcontn2kv::setmst>; + using setmv_action = eosio::action_wrapper<"setmv"_n, &nestcontn2kv::setmv>; + using setmo_action = eosio::action_wrapper<"setmo"_n, &nestcontn2kv::setmo>; + using setmm_action = eosio::action_wrapper<"setmm"_n, &nestcontn2kv::setmm>; + using setmp_action = eosio::action_wrapper<"setmp"_n, &nestcontn2kv::setmp>; + using setmt_action = eosio::action_wrapper<"setmt"_n, &nestcontn2kv::setmt>; + + using setpst_action = eosio::action_wrapper<"setpst"_n, &nestcontn2kv::setpst>; + using setpv_action = eosio::action_wrapper<"setpv"_n, &nestcontn2kv::setpv>; + using setpo_action = eosio::action_wrapper<"setpo"_n, &nestcontn2kv::setpo>; + using setpm_action = eosio::action_wrapper<"setpm"_n, &nestcontn2kv::setpm>; + using setpp_action = eosio::action_wrapper<"setpp"_n, &nestcontn2kv::setpp>; + using setpt_action = eosio::action_wrapper<"setpt"_n, &nestcontn2kv::setpt>; + + using settst_action = eosio::action_wrapper<"settst"_n, &nestcontn2kv::settst>; + using settv_action = eosio::action_wrapper<"settv"_n, &nestcontn2kv::settv>; + using setto_action = eosio::action_wrapper<"setto"_n, &nestcontn2kv::setto>; + using settm_action = eosio::action_wrapper<"settm"_n, &nestcontn2kv::settm>; + using settp_action = eosio::action_wrapper<"settp"_n, &nestcontn2kv::settp>; + using settt_action = eosio::action_wrapper<"settt"_n, &nestcontn2kv::settt>; + + + using setvos_action = eosio::action_wrapper<"setvos"_n, &nestcontn2kv::setvos>; + using setpvo_action = eosio::action_wrapper<"setpvo"_n, &nestcontn2kv::setpvo>; + +}; + diff --git a/unittests/test-contracts/nested_container_kv/nested_container_kv.wasm b/unittests/test-contracts/nested_container_kv/nested_container_kv.wasm new file mode 100755 index 0000000000000000000000000000000000000000..8d3746a0af194660a0199d2d7e7a409a322dff6a GIT binary patch literal 212741 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 is a struct with 2 fields first and second, + * std::map is handled as an array/vector of pairs/structs by EOSIO with implicit fields key, value, + * the cases of combined use of key/value and first/second involving map,pair in the cleos are documented here. + * so handling of std::pair is NOT the same as the handling of a general struct such as struct mystruct! + * + * When assigning data input with cleos: + * [] represents an empty vector/set or empty map where T, T1, T2 can be any composite types + * null represents an uninitialized std::optional where T can be any composite type + * BUT [] or null can NOT be used to represent an empty struct or empty std::pair + */ + +#include + +#include +#include +#include +#include +#include + +using namespace eosio; +using namespace std; + +#define SETCONTAINERVAL(x) do { \ + require_auth(user); \ + psninfoindex2 tblIndex(get_self(), get_first_receiver().value); \ + auto iter = tblIndex.find(user.value); \ + if (iter == tblIndex.end()) \ + { \ + tblIndex.emplace(user, [&](auto &row) { \ + row.key = user; \ + row.x = x; \ + }); \ + } \ + else \ + { \ + tblIndex.modify(iter, user, [&]( auto& row ) { \ + row.x = x; \ + }); \ + } \ + }while(0) + +struct mystruct +{ + uint64_t _count; + string _strID; +}; + + +typedef set set_uint16; +typedef vector vec_uint16; +typedef optional op_uint16; +typedef map mp_uint16; +typedef pair pr_uint16; + +typedef vector< op_uint16 > vec_op_uint16; +typedef optional< mystruct > op_struc; +typedef tuple tup_uint16; + +class [[eosio::contract("nested_container_multi_index")]] nestcontnmi : public eosio::contract { + private: + struct [[eosio::table]] person2 { + name key; + + set< set_uint16 > stst; + set< vec_uint16 > stv; + set< op_uint16 > sto; + set< mp_uint16 > stm; + set< pr_uint16 > stp; + set< tup_uint16 > stt; + + vector< set_uint16 > vst; + vector< vec_uint16 > vv; + vector< op_uint16 > vo; + vector< mp_uint16 > vm; + vector< pr_uint16 > vp; + vector< tup_uint16 > vt; + + optional< set_uint16 > ost; + optional< vec_uint16 > ov; + optional< op_uint16 > oo; + optional< mp_uint16 > om; + optional< pr_uint16 > op; + optional< tup_uint16 > ot; + + map< uint16_t, set_uint16 > mst; + map< uint16_t, vec_uint16 > mv; + map< uint16_t, op_uint16 > mo; + map< uint16_t, mp_uint16 > mm; + map< uint16_t, pr_uint16 > mp; + map< uint16_t, tup_uint16 > mt; + + pair< uint16_t, set_uint16 > pst; + pair< uint16_t, vec_uint16 > pv; + pair< uint16_t, op_uint16 > po; + pair< uint16_t, mp_uint16 > pm; + pair< uint16_t, pr_uint16 > pp; + pair< uint16_t, tup_uint16 > pt; + + tuple< uint16_t, vec_uint16, vec_uint16 > tv; + tuple< uint16_t, set_uint16, set_uint16 > tst; + tuple< op_uint16, op_uint16, op_uint16,op_uint16,op_uint16 > to; + tuple< uint16_t, mp_uint16, mp_uint16 > tm; + tuple< uint16_t, pr_uint16, pr_uint16 > tp; + tuple< tup_uint16, tup_uint16, tup_uint16 > tt; + + vector< op_struc > vos; + pair< uint16_t, vec_op_uint16 > pvo; + + uint64_t primary_key() const { return key.value; } + }; + using psninfoindex2 = eosio::multi_index<"people2"_n, person2>; + + + public: + using contract::contract; + + nestcontnmi(name receiver, name code, datastream ds): contract(receiver, code, ds) {} + + [[eosio::action]] + void setstst(name user, const set< set_uint16 >& stst){ + SETCONTAINERVAL(stst); + eosio::print("type defined set< set< uint16_t >> stored successfully!"); + } + + [[eosio::action]] + void setstv(name user, const set< vec_uint16 >& stv){ + SETCONTAINERVAL(stv); + eosio::print("type defined set< vector< uint16_t >> stored successfully!"); + } + + [[eosio::action]] + void setsto(name user, const set< op_uint16 >& sto){ + SETCONTAINERVAL(sto); + eosio::print("type defined set< optional< uint16_t >> stored successfully!"); + } + + [[eosio::action]] + void setstm(name user, const set< mp_uint16 >& stm){ + SETCONTAINERVAL(stm); + eosio::print("type defined set< map< uint16_t, uint16_t>> stored successfully!"); + } + + [[eosio::action]] + void setstp(name user, const set< pr_uint16 >& stp){ + SETCONTAINERVAL(stp); + eosio::print("type defined set< pair< uint16_t, uint16_t >> stored successfully"); + } + + [[eosio::action]] + void setstt(name user, const set< tup_uint16 >& stt){ + SETCONTAINERVAL(stt); + eosio::print("type defined set< tuple< uint16_t, uint16_t >> stored successfully!"); + } + + + [[eosio::action]] + void setvst(name user, const vector< set_uint16 >& vst){ + SETCONTAINERVAL(vst); + eosio::print("type defined vector< set< uint16_t >> stored successfully!"); + } + + [[eosio::action]] + void setvv(name user, const vector< vec_uint16 >& vv){ + SETCONTAINERVAL(vv); + eosio::print("type defined vector< vector< uint16_t >> stored successfully!"); + } + + [[eosio::action]] + void setvo(name user, const vector< op_uint16 >& vo){ + SETCONTAINERVAL(vo); + eosio::print("type defined vector< optional< uint16_t >> stored successfully!"); + } + + [[eosio::action]] + void setvm(name user, const vector< mp_uint16 >& vm){ + SETCONTAINERVAL(vm); + eosio::print("type defined vector< map< uint16_t, uint16_t>> stored successfully!"); + } + + [[eosio::action]] + void setvp(name user, const vector< pr_uint16 >& vp){ + SETCONTAINERVAL(vp); + eosio::print("type defined vector< pair< uint16_t, uint16_t >> stored successfully"); + } + + [[eosio::action]] + void setvt(name user, const vector< tup_uint16 >& vt){ + SETCONTAINERVAL(vt); + eosio::print("type defined vector< tuple< uint16_t, uint16_t >> stored successfully!"); + } + + + [[eosio::action]] + void setost(name user, const optional< set_uint16 >& ost){ + SETCONTAINERVAL(ost); + eosio::print("type defined optional< set< uint16_t >> stored successfully!"); + } + + [[eosio::action]] + void setov(name user, const optional< vec_uint16 >& ov){ + SETCONTAINERVAL(ov); + eosio::print("type defined optional< vector< uint16_t >> stored successfully!"); + } + + [[eosio::action]] + void setoo(name user, const optional< op_uint16 > & oo){ + SETCONTAINERVAL(oo); + eosio::print("type defined optional< optional< uint16_t >> stored successfully!"); + } + + [[eosio::action]] + void setom(name user, const optional< mp_uint16 >& om){ + SETCONTAINERVAL(om); + eosio::print("type defined optional< map< uint16_t, uint16_t>> stored successfully!"); + } + + [[eosio::action]] + void setop(name user, const optional< pr_uint16 >& op){ + SETCONTAINERVAL(op); + eosio::print("type defined optional< pair< uint16_t, uint16_t >> stored successfully"); + } + + [[eosio::action]] + void setot(name user, const optional< tup_uint16 >& ot){ + SETCONTAINERVAL(ot); + eosio::print("type defined optional< tuple< uint16_t, uint16_t >> stored successfully!"); + } + + + [[eosio::action]] + void setmst(name user, const map< uint16_t, set_uint16 >& mst){ + SETCONTAINERVAL(mst); + eosio::print("type defined map< set< uint16_t >> stored successfully!"); + } + + [[eosio::action]] + void setmv(name user, const map< uint16_t, vec_uint16 >& mv){ + SETCONTAINERVAL(mv); + eosio::print("type defined map< vector< uint16_t >> stored successfully!"); + } + + [[eosio::action]] + void setmo(name user, const map< uint16_t, op_uint16 > & mo){ + SETCONTAINERVAL(mo); + eosio::print("type defined map< optional< uint16_t >> stored successfully!"); + } + + [[eosio::action]] + void setmm(name user, const map< uint16_t, mp_uint16 >& mm){ + SETCONTAINERVAL(mm); + eosio::print("type defined map< map< uint16_t, uint16_t>> stored successfully!"); + } + + [[eosio::action]] + void setmp(name user, const map< uint16_t, pr_uint16 >& mp){ + SETCONTAINERVAL(mp); + eosio::print("type defined map< pair< uint16_t, uint16_t >> stored successfully"); + } + + [[eosio::action]] + void setmt(name user, const map< uint16_t, tup_uint16 >& mt){ + SETCONTAINERVAL(mt); + eosio::print("type defined map< uint16_t, tuple< uint16_t, uint16_t >> stored successfully!"); + } + + + [[eosio::action]] + void setpst(name user, const pair< uint16_t, set_uint16 >& pst){ + SETCONTAINERVAL(pst); + eosio::print("type defined pair< set< uint16_t >> stored successfully!"); + } + + [[eosio::action]] + void setpv(name user, const pair< uint16_t, vec_uint16 >& pv){ + SETCONTAINERVAL(pv); + eosio::print("type defined pair< vector< uint16_t >> stored successfully!"); + } + + [[eosio::action]] + void setpo(name user, const pair< uint16_t, op_uint16 > & po){ + SETCONTAINERVAL(po); + eosio::print("type defined pair< optional< uint16_t >> stored successfully!"); + } + + [[eosio::action]] + void setpm(name user, const pair< uint16_t, mp_uint16 >& pm){ + SETCONTAINERVAL(pm); + eosio::print("type defined pair< map< uint16_t, uint16_t>> stored successfully!"); + } + + [[eosio::action]] + void setpp(name user, const pair< uint16_t, pr_uint16 >& pp){ + SETCONTAINERVAL(pp); + eosio::print("type defined pair< pair< uint16_t, uint16_t >> stored successfully"); + } + + [[eosio::action]] + void setpt(name user, const pair< uint16_t, tup_uint16 >& pt){ + SETCONTAINERVAL(pt); + eosio::print("type defined pair< uint16_t, tuple< uint16_t, uint16_t >> stored successfully!"); + } + + [[eosio::action]] + void settst(name user, const tuple& tst){ + SETCONTAINERVAL(tst); + eosio::print("type defined tuple< uint16_t, set< uint16_t >, set< uint16_t >> stored successfully!"); + } + + [[eosio::action]] + void settv(name user, const tuple& tv){ + SETCONTAINERVAL(tv); + eosio::print("type defined tuple< uint16_t, vector< uint16_t >, vector< uint16_t > stored successfully!"); + } + + [[eosio::action]] + void setto(name user, const tuple & to){ + SETCONTAINERVAL(to); + eosio::print("type defined tuple< optional < uint16_t >, optional < uint16_t >, ... > stored successfully!"); + } + + [[eosio::action]] + void settm(name user, const tuple& tm){ + SETCONTAINERVAL(tm); + eosio::print("type defined tuple< map< uint16_t, map< uint16_t, uint16_t>, map< uint16_t, uint16_t> >> stored successfully!"); + } + + [[eosio::action]] + void settp(name user, const tuple& tp){ + SETCONTAINERVAL(tp); + eosio::print("type defined tuple< uint16_t, pair< uint16_t, uint16_t >, pair< uint16_t, uint16_t >> stored successfully"); + } + + [[eosio::action]] + void settt(name user, const tuple< tup_uint16, tup_uint16, tup_uint16 >& tt){ + SETCONTAINERVAL(tt); + eosio::print("type defined tuple< tuple< uint16_t, uint16_t >, ... > stored successfully!"); + } + + + [[eosio::action]] + void setvos(name user, const vector& vos) + { + SETCONTAINERVAL(vos); + eosio::print("vector> stored successfully"); + } + + [[eosio::action]] + void setpvo(name user, const pair& pvo) + { + SETCONTAINERVAL(pvo); + eosio::print("pair>> stored successfully"); + } +}; \ No newline at end of file diff --git a/unittests/test-contracts/nested_container_multi_index/nested_container_multi_index.wasm b/unittests/test-contracts/nested_container_multi_index/nested_container_multi_index.wasm new file mode 100755 index 0000000000000000000000000000000000000000..cd3f617680942fdcefb2f5588541774dfa3c83d4 GIT binary patch literal 227446 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 z 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 RccKi!?AEA$?usb-{{hT$)5`z= literal 0 HcmV?d00001 From 0cb6c941bfae83c546ae0478f18adc2d0cd4dabb Mon Sep 17 00:00:00 2001 From: Chris Gundlach Date: Fri, 22 Jul 2022 10:13:06 -0500 Subject: [PATCH 2/8] GH-524 took out irrelevant tests --- tests/CMakeLists.txt | 45 ------------------------- unittests/test-contracts/CMakeLists.txt | 1 - 2 files changed, 46 deletions(-) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index cf471385fd..6e4f379a8c 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -150,54 +150,9 @@ set_tests_properties(db_modes_test PROPERTIES COST 6000) add_test(NAME release-build-test COMMAND tests/release-build.sh WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) add_test(NAME version-label-test COMMAND tests/version-label.sh "v${VERSION_FULL}" WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) add_test(NAME full-version-label-test COMMAND tests/full-version-label.sh "v${VERSION_FULL}" ${CMAKE_SOURCE_DIR} WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) -<<<<<<< HEAD -======= -add_test(NAME print-build-info-test COMMAND tests/print-build-info.sh ${CMAKE_SOURCE_DIR} WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) -if(NOT EOSIO_REQUIRE_FULL_VALIDATION) - add_test(NAME light_validation_sync_test COMMAND tests/light_validation_sync_test.py -v --clean-run --dump-error-detail WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) - set_property(TEST light_validation_sync_test PROPERTY LABELS nonparallelizable_tests) - add_test(NAME eosio_blocklog_prune_test COMMAND tests/eosio_blocklog_prune_test.py -v --clean-run --dump-error-detail WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) - set_property(TEST eosio_blocklog_prune_test PROPERTY LABELS nonparallelizable_tests) -endif() -add_test(NAME privacy_startup_network COMMAND tests/privacy_startup_network.py -p 2 -v --clean-run --dump-error-detail WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) -set_property(TEST privacy_startup_network PROPERTY LABELS nonparallelizable_tests) -add_test(NAME privacy_simple_network COMMAND tests/privacy_simple_network.py -p 2 -n 3 -v --clean-run --dump-error-detail WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) -set_property(TEST privacy_simple_network PROPERTY LABELS nonparallelizable_tests) -add_test(NAME privacy_tls_test COMMAND tests/privacy_tls_test.py -v --dump-error-detail WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) -set_property(TEST privacy_tls_test PROPERTY LABELS nonparallelizable_tests) -add_test(NAME privacy_scenario_3_test COMMAND tests/privacy_scenario_3_test.py -v --dump-error-detail WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) -set_property(TEST privacy_scenario_3_test PROPERTY LABELS nonparallelizable_tests) -add_test(NAME privacy_forked_network COMMAND tests/privacy_forked_network.py -p 4 -v --dump-error-detail WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) -set_property(TEST privacy_forked_network PROPERTY LABELS nonparallelizable_tests) -add_test(NAME privacy_config_test_activate COMMAND tests/privacy_config_test_activate.py -v --dump-error-detail WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) -set_property(TEST privacy_config_test_activate PROPERTY LABELS nonparallelizable_tests) -add_test(NAME privacy_config_test_restart COMMAND tests/privacy_config_test_restart.py -v --dump-error-detail WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) -set_property(TEST privacy_config_test_restart PROPERTY LABELS nonparallelizable_tests) -add_test(NAME privacy_config_test_snapshot COMMAND tests/privacy_config_test_snapshot.py -v --dump-error-detail WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) -set_property(TEST privacy_config_test_snapshot PROPERTY LABELS nonparallelizable_tests) -add_test(NAME privacy_config_test_no_ca COMMAND tests/privacy_config_test_no_ca.py -v --dump-error-detail WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) -set_property(TEST privacy_config_test_no_ca PROPERTY LABELS nonparallelizable_tests) -add_test(NAME privacy_network_from_snapshot COMMAND tests/privacy_network_from_snapshot.py -v --dump-error-detail WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) -set_property(TEST privacy_network_from_snapshot PROPERTY LABELS nonparallelizable_tests) -add_test(NAME read_only_query COMMAND tests/read_only_query_tests.py -p 1 -v --dump-error-detail WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) -set_property(TEST read_only_query PROPERTY LABELS nonparallelizable_tests) -add_test(NAME cleos_action_no_params COMMAND tests/cleos_action_no_params.py WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) -set_property(TEST cleos_action_no_params PROPERTY LABELS nonparallelizable_tests) -add_test(NAME nested_container_kv_test COMMAND tests/nested_container_kv_test.py WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) -set_property(TEST nested_container_kv_test PROPERTY LABELS nonparallelizable_tests) add_test(NAME nested_container_multi_index_test COMMAND tests/nested_container_multi_index_test.py WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) set_property(TEST nested_container_multi_index_test PROPERTY LABELS nonparallelizable_tests) -if (ENABLE_RODEOS) - add_test(NAME rodeos_test COMMAND tests/rodeos_test.py -v --clean-run --dump-error-detail WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) - set_property(TEST rodeos_test PROPERTY LABELS nonparallelizable_tests) - if("eos-vm-oc" IN_LIST EOSIO_WASM_RUNTIMES) - add_test(NAME rodeos_test_eosvmoc COMMAND tests/rodeos_test.py -v --clean-run --dump-error-detail --eos-vm-oc-enable WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) - set_property(TEST rodeos_test_eosvmoc PROPERTY LABELS nonparallelizable_tests) - endif() -endif() ->>>>>>> da5b3c0ca... Merge pull request #10635 from EOSIO/nested_container_support_set_optional - # Long running tests add_test(NAME nodeos_sanity_lr_test COMMAND tests/nodeos_run_test.py -v --sanity-test --clean-run --dump-error-detail WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) set_property(TEST nodeos_sanity_lr_test PROPERTY LABELS long_running_tests) diff --git a/unittests/test-contracts/CMakeLists.txt b/unittests/test-contracts/CMakeLists.txt index c5d32bfa18..b9494ef1eb 100644 --- a/unittests/test-contracts/CMakeLists.txt +++ b/unittests/test-contracts/CMakeLists.txt @@ -39,6 +39,5 @@ add_subdirectory( wasm_config_bios ) add_subdirectory( params_test ) add_subdirectory( crypto_primitives_test ) add_subdirectory( get_block_num_test ) -add_subdirectory( security_group_test ) add_subdirectory( nested_container_kv ) add_subdirectory( nested_container_multi_index ) From f46c75e1e335fa0b10a8410f64361bb9d51625bf Mon Sep 17 00:00:00 2001 From: Chris Gundlach Date: Fri, 22 Jul 2022 10:30:17 -0500 Subject: [PATCH 3/8] GH-524 removed kv test contract --- unittests/test-contracts/CMakeLists.txt | 1 - .../nested_container_kv/CMakeLists.txt | 6 - .../nested_container_kv.abi | 1212 ----------------- .../nested_container_kv.cpp | 402 ------ .../nested_container_kv.wasm | Bin 212741 -> 0 bytes 5 files changed, 1621 deletions(-) delete mode 100644 unittests/test-contracts/nested_container_kv/CMakeLists.txt delete mode 100644 unittests/test-contracts/nested_container_kv/nested_container_kv.abi delete mode 100644 unittests/test-contracts/nested_container_kv/nested_container_kv.cpp delete mode 100755 unittests/test-contracts/nested_container_kv/nested_container_kv.wasm diff --git a/unittests/test-contracts/CMakeLists.txt b/unittests/test-contracts/CMakeLists.txt index b9494ef1eb..0dcb06afcd 100644 --- a/unittests/test-contracts/CMakeLists.txt +++ b/unittests/test-contracts/CMakeLists.txt @@ -39,5 +39,4 @@ add_subdirectory( wasm_config_bios ) add_subdirectory( params_test ) add_subdirectory( crypto_primitives_test ) add_subdirectory( get_block_num_test ) -add_subdirectory( nested_container_kv ) add_subdirectory( nested_container_multi_index ) diff --git a/unittests/test-contracts/nested_container_kv/CMakeLists.txt b/unittests/test-contracts/nested_container_kv/CMakeLists.txt deleted file mode 100644 index 36cc1a1f90..0000000000 --- a/unittests/test-contracts/nested_container_kv/CMakeLists.txt +++ /dev/null @@ -1,6 +0,0 @@ -if( EOSIO_COMPILE_TEST_CONTRACTS ) - add_contract( nested_container_kv nested_container_kv nested_container_kv.cpp ) -else() - configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/nested_container_kv.wasm ${CMAKE_CURRENT_BINARY_DIR}/nested_container_kv.wasm COPYONLY ) - configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/nested_container_kv.abi ${CMAKE_CURRENT_BINARY_DIR}/nested_container_kv.abi COPYONLY ) -endif() \ No newline at end of file diff --git a/unittests/test-contracts/nested_container_kv/nested_container_kv.abi b/unittests/test-contracts/nested_container_kv/nested_container_kv.abi deleted file mode 100644 index 7ca29d0719..0000000000 --- a/unittests/test-contracts/nested_container_kv/nested_container_kv.abi +++ /dev/null @@ -1,1212 +0,0 @@ -{ - "____comment": "This file was generated with eosio-abigen. DO NOT EDIT ", - "version": "eosio::abi/1.2", - "types": [ - { - "new_type_name": "mp_uint16", - "type": "pair_uint16_uint16[]" - }, - { - "new_type_name": "op_struc", - "type": "mystruct?" - }, - { - "new_type_name": "op_uint16", - "type": "uint16?" - }, - { - "new_type_name": "pr_uint16", - "type": "pair_uint16_uint16" - }, - { - "new_type_name": "set_uint16", - "type": "uint16[]" - }, - { - "new_type_name": "tup_uint16", - "type": "tuple_uint16_uint16" - }, - { - "new_type_name": "vec_op_uint16", - "type": "op_uint16[]" - }, - { - "new_type_name": "vec_uint16", - "type": "uint16[]" - } - ], - "structs": [ - { - "name": "get", - "base": "", - "fields": [ - { - "name": "id", - "type": "int32" - } - ] - }, - { - "name": "mystruct", - "base": "", - "fields": [ - { - "name": "_count", - "type": "uint64" - }, - { - "name": "_strID", - "type": "string" - } - ] - }, - { - "name": "pair_uint16_mp_uint16", - "base": "", - "fields": [ - { - "name": "key", - "type": "uint16" - }, - { - "name": "value", - "type": "mp_uint16" - } - ] - }, - { - "name": "pair_uint16_op_uint16", - "base": "", - "fields": [ - { - "name": "key", - "type": "uint16" - }, - { - "name": "value", - "type": "op_uint16" - } - ] - }, - { - "name": "pair_uint16_pr_uint16", - "base": "", - "fields": [ - { - "name": "key", - "type": "uint16" - }, - { - "name": "value", - "type": "pr_uint16" - } - ] - }, - { - "name": "pair_uint16_set_uint16", - "base": "", - "fields": [ - { - "name": "key", - "type": "uint16" - }, - { - "name": "value", - "type": "set_uint16" - } - ] - }, - { - "name": "pair_uint16_tup_uint16", - "base": "", - "fields": [ - { - "name": "key", - "type": "uint16" - }, - { - "name": "value", - "type": "tup_uint16" - } - ] - }, - { - "name": "pair_uint16_uint16", - "base": "", - "fields": [ - { - "name": "key", - "type": "uint16" - }, - { - "name": "value", - "type": "uint16" - } - ] - }, - { - "name": "pair_uint16_vec_op_uint16", - "base": "", - "fields": [ - { - "name": "first", - "type": "uint16" - }, - { - "name": "second", - "type": "vec_op_uint16" - } - ] - }, - { - "name": "pair_uint16_vec_uint16", - "base": "", - "fields": [ - { - "name": "key", - "type": "uint16" - }, - { - "name": "value", - "type": "vec_uint16" - } - ] - }, - { - "name": "person2kv", - "base": "", - "fields": [ - { - "name": "stst", - "type": "set_uint16[]" - }, - { - "name": "stv", - "type": "vec_uint16[]" - }, - { - "name": "sto", - "type": "op_uint16[]" - }, - { - "name": "stm", - "type": "mp_uint16[]" - }, - { - "name": "stp", - "type": "pr_uint16[]" - }, - { - "name": "stt", - "type": "tup_uint16[]" - }, - { - "name": "vst", - "type": "set_uint16[]" - }, - { - "name": "vv", - "type": "vec_uint16[]" - }, - { - "name": "vo", - "type": "op_uint16[]" - }, - { - "name": "vm", - "type": "mp_uint16[]" - }, - { - "name": "vp", - "type": "pr_uint16[]" - }, - { - "name": "vt", - "type": "tup_uint16[]" - }, - { - "name": "ost", - "type": "set_uint16?" - }, - { - "name": "ov", - "type": "vec_uint16?" - }, - { - "name": "oo", - "type": "op_uint16?" - }, - { - "name": "om", - "type": "mp_uint16?" - }, - { - "name": "op", - "type": "pr_uint16?" - }, - { - "name": "ot", - "type": "tup_uint16?" - }, - { - "name": "mst", - "type": "pair_uint16_set_uint16[]" - }, - { - "name": "mv", - "type": "pair_uint16_vec_uint16[]" - }, - { - "name": "mo", - "type": "pair_uint16_op_uint16[]" - }, - { - "name": "mm", - "type": "pair_uint16_mp_uint16[]" - }, - { - "name": "mp", - "type": "pair_uint16_pr_uint16[]" - }, - { - "name": "mt", - "type": "pair_uint16_tup_uint16[]" - }, - { - "name": "pst", - "type": "pair_uint16_set_uint16" - }, - { - "name": "pv", - "type": "pair_uint16_vec_uint16" - }, - { - "name": "po", - "type": "pair_uint16_op_uint16" - }, - { - "name": "pm", - "type": "pair_uint16_mp_uint16" - }, - { - "name": "pp", - "type": "pair_uint16_pr_uint16" - }, - { - "name": "pt", - "type": "pair_uint16_tup_uint16" - }, - { - "name": "tv", - "type": "tuple_uint16_vec_uint16_vec_uint16" - }, - { - "name": "tst", - "type": "tuple_uint16_set_uint16_set_uint16" - }, - { - "name": "to", - "type": "tuple_op_uint16_op_uint16_op_uint16_op_uint16_op_uint16" - }, - { - "name": "tm", - "type": "tuple_uint16_mp_uint16_mp_uint16" - }, - { - "name": "tp", - "type": "tuple_uint16_pr_uint16_pr_uint16" - }, - { - "name": "tt", - "type": "tuple_tup_uint16_tup_uint16_tup_uint16" - }, - { - "name": "vos", - "type": "op_struc[]" - }, - { - "name": "pvo", - "type": "pair_uint16_vec_op_uint16" - } - ] - }, - { - "name": "setmm", - "base": "", - "fields": [ - { - "name": "id", - "type": "int32" - }, - { - "name": "mm", - "type": "pair_uint16_mp_uint16[]" - } - ] - }, - { - "name": "setmo", - "base": "", - "fields": [ - { - "name": "id", - "type": "int32" - }, - { - "name": "mo", - "type": "pair_uint16_op_uint16[]" - } - ] - }, - { - "name": "setmp", - "base": "", - "fields": [ - { - "name": "id", - "type": "int32" - }, - { - "name": "mp", - "type": "pair_uint16_pr_uint16[]" - } - ] - }, - { - "name": "setmst", - "base": "", - "fields": [ - { - "name": "id", - "type": "int32" - }, - { - "name": "mst", - "type": "pair_uint16_set_uint16[]" - } - ] - }, - { - "name": "setmt", - "base": "", - "fields": [ - { - "name": "id", - "type": "int32" - }, - { - "name": "mt", - "type": "pair_uint16_tup_uint16[]" - } - ] - }, - { - "name": "setmv", - "base": "", - "fields": [ - { - "name": "id", - "type": "int32" - }, - { - "name": "mv", - "type": "pair_uint16_vec_uint16[]" - } - ] - }, - { - "name": "setom", - "base": "", - "fields": [ - { - "name": "id", - "type": "int32" - }, - { - "name": "om", - "type": "mp_uint16?" - } - ] - }, - { - "name": "setoo", - "base": "", - "fields": [ - { - "name": "id", - "type": "int32" - }, - { - "name": "oo", - "type": "op_uint16?" - } - ] - }, - { - "name": "setop", - "base": "", - "fields": [ - { - "name": "id", - "type": "int32" - }, - { - "name": "op", - "type": "pr_uint16?" - } - ] - }, - { - "name": "setost", - "base": "", - "fields": [ - { - "name": "id", - "type": "int32" - }, - { - "name": "ost", - "type": "set_uint16?" - } - ] - }, - { - "name": "setot", - "base": "", - "fields": [ - { - "name": "id", - "type": "int32" - }, - { - "name": "ot", - "type": "tup_uint16?" - } - ] - }, - { - "name": "setov", - "base": "", - "fields": [ - { - "name": "id", - "type": "int32" - }, - { - "name": "ov", - "type": "vec_uint16?" - } - ] - }, - { - "name": "setpm", - "base": "", - "fields": [ - { - "name": "id", - "type": "int32" - }, - { - "name": "pm", - "type": "pair_uint16_mp_uint16" - } - ] - }, - { - "name": "setpo", - "base": "", - "fields": [ - { - "name": "id", - "type": "int32" - }, - { - "name": "po", - "type": "pair_uint16_op_uint16" - } - ] - }, - { - "name": "setpp", - "base": "", - "fields": [ - { - "name": "id", - "type": "int32" - }, - { - "name": "pp", - "type": "pair_uint16_pr_uint16" - } - ] - }, - { - "name": "setpst", - "base": "", - "fields": [ - { - "name": "id", - "type": "int32" - }, - { - "name": "pst", - "type": "pair_uint16_set_uint16" - } - ] - }, - { - "name": "setpt", - "base": "", - "fields": [ - { - "name": "id", - "type": "int32" - }, - { - "name": "pt", - "type": "pair_uint16_tup_uint16" - } - ] - }, - { - "name": "setpv", - "base": "", - "fields": [ - { - "name": "id", - "type": "int32" - }, - { - "name": "pv", - "type": "pair_uint16_vec_uint16" - } - ] - }, - { - "name": "setpvo", - "base": "", - "fields": [ - { - "name": "id", - "type": "int32" - }, - { - "name": "pvo", - "type": "pair_uint16_vec_op_uint16" - } - ] - }, - { - "name": "setstm", - "base": "", - "fields": [ - { - "name": "id", - "type": "int32" - }, - { - "name": "stm", - "type": "mp_uint16[]" - } - ] - }, - { - "name": "setsto", - "base": "", - "fields": [ - { - "name": "id", - "type": "int32" - }, - { - "name": "sto", - "type": "op_uint16[]" - } - ] - }, - { - "name": "setstp", - "base": "", - "fields": [ - { - "name": "id", - "type": "int32" - }, - { - "name": "stp", - "type": "pr_uint16[]" - } - ] - }, - { - "name": "setstst", - "base": "", - "fields": [ - { - "name": "id", - "type": "int32" - }, - { - "name": "stst", - "type": "set_uint16[]" - } - ] - }, - { - "name": "setstt", - "base": "", - "fields": [ - { - "name": "id", - "type": "int32" - }, - { - "name": "stt", - "type": "tup_uint16[]" - } - ] - }, - { - "name": "setstv", - "base": "", - "fields": [ - { - "name": "id", - "type": "int32" - }, - { - "name": "stv", - "type": "vec_uint16[]" - } - ] - }, - { - "name": "settm", - "base": "", - "fields": [ - { - "name": "id", - "type": "int32" - }, - { - "name": "tm", - "type": "tuple_uint16_mp_uint16_mp_uint16" - } - ] - }, - { - "name": "setto", - "base": "", - "fields": [ - { - "name": "id", - "type": "int32" - }, - { - "name": "to", - "type": "tuple_op_uint16_op_uint16_op_uint16_op_uint16_op_uint16" - } - ] - }, - { - "name": "settp", - "base": "", - "fields": [ - { - "name": "id", - "type": "int32" - }, - { - "name": "tp", - "type": "tuple_uint16_pr_uint16_pr_uint16" - } - ] - }, - { - "name": "settst", - "base": "", - "fields": [ - { - "name": "id", - "type": "int32" - }, - { - "name": "tst", - "type": "tuple_uint16_set_uint16_set_uint16" - } - ] - }, - { - "name": "settt", - "base": "", - "fields": [ - { - "name": "id", - "type": "int32" - }, - { - "name": "tt", - "type": "tuple_tup_uint16_tup_uint16_tup_uint16" - } - ] - }, - { - "name": "settv", - "base": "", - "fields": [ - { - "name": "id", - "type": "int32" - }, - { - "name": "tv", - "type": "tuple_uint16_vec_uint16_vec_uint16" - } - ] - }, - { - "name": "setvm", - "base": "", - "fields": [ - { - "name": "id", - "type": "int32" - }, - { - "name": "vm", - "type": "mp_uint16[]" - } - ] - }, - { - "name": "setvo", - "base": "", - "fields": [ - { - "name": "id", - "type": "int32" - }, - { - "name": "vo", - "type": "op_uint16[]" - } - ] - }, - { - "name": "setvos", - "base": "", - "fields": [ - { - "name": "id", - "type": "int32" - }, - { - "name": "vos", - "type": "op_struc[]" - } - ] - }, - { - "name": "setvp", - "base": "", - "fields": [ - { - "name": "id", - "type": "int32" - }, - { - "name": "vp", - "type": "pr_uint16[]" - } - ] - }, - { - "name": "setvst", - "base": "", - "fields": [ - { - "name": "id", - "type": "int32" - }, - { - "name": "vst", - "type": "set_uint16[]" - } - ] - }, - { - "name": "setvt", - "base": "", - "fields": [ - { - "name": "id", - "type": "int32" - }, - { - "name": "vt", - "type": "tup_uint16[]" - } - ] - }, - { - "name": "setvv", - "base": "", - "fields": [ - { - "name": "id", - "type": "int32" - }, - { - "name": "vv", - "type": "vec_uint16[]" - } - ] - }, - { - "name": "tuple_op_uint16_op_uint16_op_uint16_op_uint16_op_uint16", - "base": "", - "fields": [ - { - "name": "field_0", - "type": "op_uint16" - }, - { - "name": "field_1", - "type": "op_uint16" - }, - { - "name": "field_2", - "type": "op_uint16" - }, - { - "name": "field_3", - "type": "op_uint16" - }, - { - "name": "field_4", - "type": "op_uint16" - } - ] - }, - { - "name": "tuple_tup_uint16_tup_uint16_tup_uint16", - "base": "", - "fields": [ - { - "name": "field_0", - "type": "tup_uint16" - }, - { - "name": "field_1", - "type": "tup_uint16" - }, - { - "name": "field_2", - "type": "tup_uint16" - } - ] - }, - { - "name": "tuple_uint16_mp_uint16_mp_uint16", - "base": "", - "fields": [ - { - "name": "field_0", - "type": "uint16" - }, - { - "name": "field_1", - "type": "mp_uint16" - }, - { - "name": "field_2", - "type": "mp_uint16" - } - ] - }, - { - "name": "tuple_uint16_pr_uint16_pr_uint16", - "base": "", - "fields": [ - { - "name": "field_0", - "type": "uint16" - }, - { - "name": "field_1", - "type": "pr_uint16" - }, - { - "name": "field_2", - "type": "pr_uint16" - } - ] - }, - { - "name": "tuple_uint16_set_uint16_set_uint16", - "base": "", - "fields": [ - { - "name": "field_0", - "type": "uint16" - }, - { - "name": "field_1", - "type": "set_uint16" - }, - { - "name": "field_2", - "type": "set_uint16" - } - ] - }, - { - "name": "tuple_uint16_uint16", - "base": "", - "fields": [ - { - "name": "field_0", - "type": "uint16" - }, - { - "name": "field_1", - "type": "uint16" - } - ] - }, - { - "name": "tuple_uint16_vec_uint16_vec_uint16", - "base": "", - "fields": [ - { - "name": "field_0", - "type": "uint16" - }, - { - "name": "field_1", - "type": "vec_uint16" - }, - { - "name": "field_2", - "type": "vec_uint16" - } - ] - } - ], - "actions": [ - { - "name": "get", - "type": "get", - "ricardian_contract": "" - }, - { - "name": "setmm", - "type": "setmm", - "ricardian_contract": "" - }, - { - "name": "setmo", - "type": "setmo", - "ricardian_contract": "" - }, - { - "name": "setmp", - "type": "setmp", - "ricardian_contract": "" - }, - { - "name": "setmst", - "type": "setmst", - "ricardian_contract": "" - }, - { - "name": "setmt", - "type": "setmt", - "ricardian_contract": "" - }, - { - "name": "setmv", - "type": "setmv", - "ricardian_contract": "" - }, - { - "name": "setom", - "type": "setom", - "ricardian_contract": "" - }, - { - "name": "setoo", - "type": "setoo", - "ricardian_contract": "" - }, - { - "name": "setop", - "type": "setop", - "ricardian_contract": "" - }, - { - "name": "setost", - "type": "setost", - "ricardian_contract": "" - }, - { - "name": "setot", - "type": "setot", - "ricardian_contract": "" - }, - { - "name": "setov", - "type": "setov", - "ricardian_contract": "" - }, - { - "name": "setpm", - "type": "setpm", - "ricardian_contract": "" - }, - { - "name": "setpo", - "type": "setpo", - "ricardian_contract": "" - }, - { - "name": "setpp", - "type": "setpp", - "ricardian_contract": "" - }, - { - "name": "setpst", - "type": "setpst", - "ricardian_contract": "" - }, - { - "name": "setpt", - "type": "setpt", - "ricardian_contract": "" - }, - { - "name": "setpv", - "type": "setpv", - "ricardian_contract": "" - }, - { - "name": "setpvo", - "type": "setpvo", - "ricardian_contract": "" - }, - { - "name": "setstm", - "type": "setstm", - "ricardian_contract": "" - }, - { - "name": "setsto", - "type": "setsto", - "ricardian_contract": "" - }, - { - "name": "setstp", - "type": "setstp", - "ricardian_contract": "" - }, - { - "name": "setstst", - "type": "setstst", - "ricardian_contract": "" - }, - { - "name": "setstt", - "type": "setstt", - "ricardian_contract": "" - }, - { - "name": "setstv", - "type": "setstv", - "ricardian_contract": "" - }, - { - "name": "settm", - "type": "settm", - "ricardian_contract": "" - }, - { - "name": "setto", - "type": "setto", - "ricardian_contract": "" - }, - { - "name": "settp", - "type": "settp", - "ricardian_contract": "" - }, - { - "name": "settst", - "type": "settst", - "ricardian_contract": "" - }, - { - "name": "settt", - "type": "settt", - "ricardian_contract": "" - }, - { - "name": "settv", - "type": "settv", - "ricardian_contract": "" - }, - { - "name": "setvm", - "type": "setvm", - "ricardian_contract": "" - }, - { - "name": "setvo", - "type": "setvo", - "ricardian_contract": "" - }, - { - "name": "setvos", - "type": "setvos", - "ricardian_contract": "" - }, - { - "name": "setvp", - "type": "setvp", - "ricardian_contract": "" - }, - { - "name": "setvst", - "type": "setvst", - "ricardian_contract": "" - }, - { - "name": "setvt", - "type": "setvt", - "ricardian_contract": "" - }, - { - "name": "setvv", - "type": "setvv", - "ricardian_contract": "" - } - ], - "tables": [], - "kv_tables": { - "people2kv": { - "type": "person2kv", - "primary_index": { - "name": "map.index", - "type": "int32" - }, - "secondary_indices": {} - } - }, - "ricardian_clauses": [], - "variants": [], - "action_results": [ - { - "name": "get", - "result_type": "person2kv" - } - ] -} \ No newline at end of file diff --git a/unittests/test-contracts/nested_container_kv/nested_container_kv.cpp b/unittests/test-contracts/nested_container_kv/nested_container_kv.cpp deleted file mode 100644 index f51661949e..0000000000 --- a/unittests/test-contracts/nested_container_kv/nested_container_kv.cpp +++ /dev/null @@ -1,402 +0,0 @@ -/* Verify the support of nested containers for the new Key-value table eosio::kv::map - * For each action, an example regarding how to use the action with the cleos command line is given. - * - * std:pair is a struct with 2 fields first and second, - * std::map is handled as an array/vector of pairs/structs by EOSIO with implicit fields key, value, - * the cases of combined use of key/value and first/second involving map,pair in the cleos are documented here, - * so handling of std::pair is NOT the same as the handling of a general struct such as struct mystruct! - * - * When assigning data input with cleos: - * [] represents an empty vector/set or empty map where T, T1, T2 can be any composite types - * null represents an uninitialized std::optional where T can be any composite type - * BUT [] or null can NOT be used to represent an empty struct or empty std::pair - * - * Attention: - * 1) Please follow https://github.com/EOSIO/eos/tree/develop/contracts/enable-kv to enable key-value support of nodeos first - * 2) To get to the point right away, here authentication/permission checking is skipped for each action in this contract, - * however in practice, suitable permission checking such as require_auth(user) has to be used! - * - */ - -#include -#include - -#include -#include -#include -#include -#include - -using namespace eosio; -using namespace std; - - -#define SETCONTAINERVAL(x) do { \ - person2kv obj = mymap[id]; \ - obj.x = x; \ - mymap[id] = obj; \ - }while(0) - -struct mystruct -{ - uint64_t _count; - string _strID; -}; - -typedef set set_uint16; -typedef vector vec_uint16; -typedef optional op_uint16; -typedef map mp_uint16; -typedef pair pr_uint16; - -typedef vector< op_uint16 > vec_op_uint16; -typedef optional< mystruct > op_struc; -typedef tuple tup_uint16; - -struct person2kv { - set< set_uint16 > stst; - set< vec_uint16 > stv; - set< op_uint16 > sto; - set< mp_uint16 > stm; - set< pr_uint16 > stp; - set< tup_uint16 > stt; - - vector< set_uint16 > vst; - vector< vec_uint16 > vv; - vector< op_uint16 > vo; - vector< mp_uint16 > vm; - vector< pr_uint16 > vp; - vector< tup_uint16 > vt; - - optional< set_uint16 > ost; - optional< vec_uint16 > ov; - optional< op_uint16 > oo; - optional< mp_uint16 > om; - optional< pr_uint16 > op; - optional< tup_uint16 > ot; - - map< uint16_t, set_uint16 > mst; - map< uint16_t, vec_uint16 > mv; - map< uint16_t, op_uint16 > mo; - map< uint16_t, mp_uint16 > mm; - map< uint16_t, pr_uint16 > mp; - map< uint16_t, tup_uint16 > mt; - - pair< uint16_t, set_uint16 > pst; - pair< uint16_t, vec_uint16 > pv; - pair< uint16_t, op_uint16 > po; - pair< uint16_t, mp_uint16 > pm; - pair< uint16_t, pr_uint16 > pp; - pair< uint16_t, tup_uint16 > pt; - - tuple< uint16_t, vec_uint16, vec_uint16 > tv; - tuple< uint16_t, set_uint16, set_uint16 > tst; - tuple< op_uint16, op_uint16, op_uint16,op_uint16,op_uint16 > to; - tuple< uint16_t, mp_uint16, mp_uint16 > tm; - tuple< uint16_t, pr_uint16, pr_uint16 > tp; - tuple< tup_uint16, tup_uint16, tup_uint16 > tt; - - vector< op_struc > vos; - pair< uint16_t, vec_op_uint16 > pvo; -}; - -class [[eosio::contract("nested_container_kv")]] nestcontn2kv : public eosio::contract { - using my_map_t = eosio::kv::map<"people2kv"_n, int, person2kv>; - - private: - my_map_t mymap{}; - - public: - using contract::contract; - - nestcontn2kv(name receiver, name code, datastream ds): contract(receiver, code, ds) {} - - [[eosio::action]] - person2kv get(int id){ - //This action will be used by all prntx actions to retrieve item_found for given id - auto iter = mymap.find(id); - check(iter != mymap.end(), "Record does not exist"); - const auto& item_found = iter->second(); - return item_found; - } - - [[eosio::action]] - void setstst(int id, const set< set_uint16 >& stst){ - SETCONTAINERVAL(stst); - eosio::print("type defined set< set< uint16_t >> stored successfully!"); - } - - [[eosio::action]] - void setstv(int id, const set< vec_uint16 >& stv){ - SETCONTAINERVAL(stv); - eosio::print("type defined set< vector< uint16_t >> stored successfully!"); - } - - [[eosio::action]] - void setsto(int id, const set< op_uint16 >& sto){ - SETCONTAINERVAL(sto); - eosio::print("type defined set< optional< uint16_t >> stored successfully!"); - } - - [[eosio::action]] - void setstm(int id, const set< mp_uint16 >& stm){ - SETCONTAINERVAL(stm); - eosio::print("type defined set< map< uint16_t, uint16_t>> stored successfully!"); - } - - [[eosio::action]] - void setstp(int id, const set< pr_uint16 >& stp){ - SETCONTAINERVAL(stp); - eosio::print("type defined set< pair< uint16_t, uint16_t >> stored successfully"); - } - - [[eosio::action]] - void setstt(int id, const set< tup_uint16 >& stt){ - SETCONTAINERVAL(stt); - eosio::print("type defined set< tuple< uint16_t, uint16_t >> stored successfully!"); - } - - - [[eosio::action]] - void setvst(int id, const vector< set_uint16 >& vst){ - SETCONTAINERVAL(vst); - eosio::print("type defined vector< set< uint16_t >> stored successfully!"); - } - - [[eosio::action]] - void setvv(int id, const vector< vec_uint16 >& vv){ - SETCONTAINERVAL(vv); - eosio::print("type defined vector< vector< uint16_t >> stored successfully!"); - } - - [[eosio::action]] - void setvo(int id, const vector< op_uint16 >& vo){ - SETCONTAINERVAL(vo); - eosio::print("type defined vector< optional< uint16_t >> stored successfully!"); - } - - [[eosio::action]] - void setvm(int id, const vector< mp_uint16 >& vm){ - SETCONTAINERVAL(vm); - eosio::print("type defined vector< map< uint16_t, uint16_t>> stored successfully!"); - } - - [[eosio::action]] - void setvp(int id, const vector< pr_uint16 >& vp){ - SETCONTAINERVAL(vp); - eosio::print("type defined vector< pair< uint16_t, uint16_t >> stored successfully"); - } - - [[eosio::action]] - void setvt(int id, const vector& vt){ - SETCONTAINERVAL(vt); - eosio::print("type defined vector< tuple< uint16_t, uint16_t >> stored successfully!"); - } - - - [[eosio::action]] - void setost(int id, const optional< set_uint16 >& ost){ - SETCONTAINERVAL(ost); - eosio::print("type defined optional< set< uint16_t >> stored successfully!"); - } - - [[eosio::action]] - void setov(int id, const optional< vec_uint16 >& ov){ - SETCONTAINERVAL(ov); - eosio::print("type defined optional< vector< uint16_t >> stored successfully!"); - } - - [[eosio::action]] - void setoo(int id, const optional< op_uint16 > & oo){ - SETCONTAINERVAL(oo); - eosio::print("type defined optional< optional< uint16_t >> stored successfully!"); - } - - [[eosio::action]] - void setom(int id, const optional< mp_uint16 >& om){ - SETCONTAINERVAL(om); - eosio::print("type defined optional< map< uint16_t, uint16_t>> stored successfully!"); - } - - [[eosio::action]] - void setop(int id, const optional< pr_uint16 >& op){ - SETCONTAINERVAL(op); - eosio::print("type defined optional< pair< uint16_t, uint16_t >> stored successfully"); - } - - [[eosio::action]] - void setot(int id, const optional& ot){ - SETCONTAINERVAL(ot); - eosio::print("type defined optional< tuple< uint16_t, uint16_t >> stored successfully!"); - } - - [[eosio::action]] - void setmst(int id, const map< uint16_t, set_uint16 >& mst){ - SETCONTAINERVAL(mst); - eosio::print("type defined map< set< uint16_t >> stored successfully!"); - } - - [[eosio::action]] - void setmv(int id, const map< uint16_t, vec_uint16 >& mv){ - SETCONTAINERVAL(mv); - eosio::print("type defined map< vector< uint16_t >> stored successfully!"); - } - - [[eosio::action]] - void setmo(int id, const map< uint16_t, op_uint16 > & mo){ - SETCONTAINERVAL(mo); - eosio::print("type defined map< optional< uint16_t >> stored successfully!"); - } - - [[eosio::action]] - void setmm(int id, const map< uint16_t, mp_uint16 >& mm){ - SETCONTAINERVAL(mm); - eosio::print("type defined map< map< uint16_t, uint16_t >> stored successfully!"); - } - - [[eosio::action]] - void setmp(int id, const map< uint16_t, pr_uint16 >& mp){ - SETCONTAINERVAL(mp); - eosio::print("type defined map< pair< uint16_t, uint16_t >> stored successfully"); - } - - [[eosio::action]] - void setmt(int id, const map& mt){ - SETCONTAINERVAL(mt); - eosio::print("type defined map< uint16_t, tuple< uint16_t, uint16_t >> stored successfully!"); - } - - [[eosio::action]] - void setpst(int id, const pair< uint16_t, set_uint16 >& pst){ - SETCONTAINERVAL(pst); - eosio::print("type defined pair< set< uint16_t >> stored successfully!"); - } - - [[eosio::action]] - void setpv(int id, const pair< uint16_t, vec_uint16 >& pv){ - SETCONTAINERVAL(pv); - eosio::print("type defined pair< vector< uint16_t >> stored successfully!"); - } - - [[eosio::action]] - void setpo(int id, const pair< uint16_t, op_uint16 > & po){ - SETCONTAINERVAL(po); - eosio::print("type defined pair< optional< uint16_t >> stored successfully!"); - } - - [[eosio::action]] - void setpm(int id, const pair< uint16_t, mp_uint16 >& pm){ - SETCONTAINERVAL(pm); - eosio::print("type defined pair< map< uint16_t, uint16_t>> stored successfully!"); - } - - [[eosio::action]] - void setpp(int id, const pair< uint16_t, pr_uint16 >& pp){ - SETCONTAINERVAL(pp); - eosio::print("type defined pair< pair< uint16_t, uint16_t >> stored successfully"); - } - - [[eosio::action]] - void setpt(int id, const pair& pt){ - SETCONTAINERVAL(pt); - eosio::print("type defined pair< uint16_t, tuple< uint16_t, uint16_t >> stored successfully!"); - } - - [[eosio::action]] - void settst(int id, const tuple& tst){ - SETCONTAINERVAL(tst); - eosio::print("type defined tuple< uint16_t, set< uint16_t >, set< uint16_t >> stored successfully!"); - } - - [[eosio::action]] - void settv(int id, const tuple& tv){ - SETCONTAINERVAL(tv); - eosio::print("type defined tuple< uint16_t, vector< uint16_t >, vector< uint16_t > stored successfully!"); - } - - [[eosio::action]] - void setto(int id, const tuple & to){ - SETCONTAINERVAL(to); - eosio::print("type defined tuple< optional < uint16_t >, optional < uint16_t >, ... > stored successfully!"); - } - - [[eosio::action]] - void settm(int id, const tuple& tm){ - SETCONTAINERVAL(tm); - eosio::print("type defined tuple< map< uint16_t, map< uint16_t, uint16_t>, map< uint16_t, uint16_t> >> stored successfully!"); - } - - [[eosio::action]] - void settp(int id, const tuple& tp){ - SETCONTAINERVAL(tp); - eosio::print("type defined tuple< uint16_t, pair< uint16_t, uint16_t >, pair< uint16_t, uint16_t >> stored successfully"); - } - - [[eosio::action]] - void settt(int id, const tuple< tup_uint16, tup_uint16, tup_uint16 >& tt){ - SETCONTAINERVAL(tt); - eosio::print("type defined tuple< tuple< uint16_t, uint16_t >, ... > stored successfully!"); - } - - [[eosio::action]] - void setvos(int id, const vector& vos){ - SETCONTAINERVAL(vos); - eosio::print("vector> stored successfully"); - } - - [[eosio::action]] - void setpvo(int id, const pair& pvo){ - SETCONTAINERVAL(pvo); - eosio::print("pair>> stored successfully"); - } - - using get_action = eosio::action_wrapper<"get"_n, &nestcontn2kv::get>; - - using setstst_action = eosio::action_wrapper<"setstst"_n, &nestcontn2kv::setstst>; - using setstv_action = eosio::action_wrapper<"setstv"_n, &nestcontn2kv::setstv>; - using setsto_action = eosio::action_wrapper<"setsto"_n, &nestcontn2kv::setsto>; - using setstm_action = eosio::action_wrapper<"setstm"_n, &nestcontn2kv::setstm>; - using setstp_action = eosio::action_wrapper<"setstp"_n, &nestcontn2kv::setstp>; - using setstt_action = eosio::action_wrapper<"setstt"_n, &nestcontn2kv::setstt>; - - using setvst_action = eosio::action_wrapper<"setvst"_n, &nestcontn2kv::setvst>; - using setvv_action = eosio::action_wrapper<"setvv"_n, &nestcontn2kv::setvv>; - using setvo_action = eosio::action_wrapper<"setvo"_n, &nestcontn2kv::setvo>; - using setvm_action = eosio::action_wrapper<"setvm"_n, &nestcontn2kv::setvm>; - using setvp_action = eosio::action_wrapper<"setvp"_n, &nestcontn2kv::setvp>; - using setvt_action = eosio::action_wrapper<"setvt"_n, &nestcontn2kv::setvt>; - - using setost_action = eosio::action_wrapper<"setost"_n, &nestcontn2kv::setost>; - using setov_action = eosio::action_wrapper<"setov"_n, &nestcontn2kv::setov>; - using setoo_action = eosio::action_wrapper<"setoo"_n, &nestcontn2kv::setoo>; - using setom_action = eosio::action_wrapper<"setom"_n, &nestcontn2kv::setom>; - using setop_action = eosio::action_wrapper<"setop"_n, &nestcontn2kv::setop>; - using setot_action = eosio::action_wrapper<"setot"_n, &nestcontn2kv::setot>; - - using setmst_action = eosio::action_wrapper<"setmst"_n, &nestcontn2kv::setmst>; - using setmv_action = eosio::action_wrapper<"setmv"_n, &nestcontn2kv::setmv>; - using setmo_action = eosio::action_wrapper<"setmo"_n, &nestcontn2kv::setmo>; - using setmm_action = eosio::action_wrapper<"setmm"_n, &nestcontn2kv::setmm>; - using setmp_action = eosio::action_wrapper<"setmp"_n, &nestcontn2kv::setmp>; - using setmt_action = eosio::action_wrapper<"setmt"_n, &nestcontn2kv::setmt>; - - using setpst_action = eosio::action_wrapper<"setpst"_n, &nestcontn2kv::setpst>; - using setpv_action = eosio::action_wrapper<"setpv"_n, &nestcontn2kv::setpv>; - using setpo_action = eosio::action_wrapper<"setpo"_n, &nestcontn2kv::setpo>; - using setpm_action = eosio::action_wrapper<"setpm"_n, &nestcontn2kv::setpm>; - using setpp_action = eosio::action_wrapper<"setpp"_n, &nestcontn2kv::setpp>; - using setpt_action = eosio::action_wrapper<"setpt"_n, &nestcontn2kv::setpt>; - - using settst_action = eosio::action_wrapper<"settst"_n, &nestcontn2kv::settst>; - using settv_action = eosio::action_wrapper<"settv"_n, &nestcontn2kv::settv>; - using setto_action = eosio::action_wrapper<"setto"_n, &nestcontn2kv::setto>; - using settm_action = eosio::action_wrapper<"settm"_n, &nestcontn2kv::settm>; - using settp_action = eosio::action_wrapper<"settp"_n, &nestcontn2kv::settp>; - using settt_action = eosio::action_wrapper<"settt"_n, &nestcontn2kv::settt>; - - - using setvos_action = eosio::action_wrapper<"setvos"_n, &nestcontn2kv::setvos>; - using setpvo_action = eosio::action_wrapper<"setpvo"_n, &nestcontn2kv::setpvo>; - -}; - diff --git a/unittests/test-contracts/nested_container_kv/nested_container_kv.wasm b/unittests/test-contracts/nested_container_kv/nested_container_kv.wasm deleted file mode 100755 index 8d3746a0af194660a0199d2d7e7a409a322dff6a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 212741 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 Date: Fri, 29 Jul 2022 08:20:56 -0500 Subject: [PATCH 4/8] re-compiled nested_container test contract --- .../nested_container_multi_index.abi | 1 - .../nested_container_multi_index.wasm | Bin 227446 -> 227450 bytes 2 files changed, 1 deletion(-) diff --git a/unittests/test-contracts/nested_container_multi_index/nested_container_multi_index.abi b/unittests/test-contracts/nested_container_multi_index/nested_container_multi_index.abi index c0a8046d91..c3538e15be 100644 --- a/unittests/test-contracts/nested_container_multi_index/nested_container_multi_index.abi +++ b/unittests/test-contracts/nested_container_multi_index/nested_container_multi_index.abi @@ -1188,7 +1188,6 @@ "key_types": [] } ], - "kv_tables": {}, "ricardian_clauses": [], "variants": [], "action_results": [] diff --git a/unittests/test-contracts/nested_container_multi_index/nested_container_multi_index.wasm b/unittests/test-contracts/nested_container_multi_index/nested_container_multi_index.wasm index cd3f617680942fdcefb2f5588541774dfa3c83d4..be3494a3cec7903ba3a7bee4dcc4c06789823755 100755 GIT binary patch delta 1251 zcmaKrUrbw79LMkP-gXpkyWXxaXxZ9R!Y(Zc3b+YK+TIJS4Mt!aV=xC}Q0O0^QVJM# zDh?Bk+jPrsVaBIDxzr_wc%obOV6vGQm6z#U+!AA=FD}ss7IhCk41c$*{&~Qg^wabE zp6~gc-#x!`@2}bZT(hlwCE=>Ho3BgnfTip3Xl&%gM}Fta<}n$Ul_9hI8i0uRVlI5a zaU6np-?0oKJiToVG*Ow>SsRnf7>wNO%s7YonEL_HR{qxQn&Iz9IMf;v3u?)qCd z)>t0uj*3GN!DPi)Mbsw9%*3QUVjnZr4bz*IG z8!=HGCg!SxhMre;`AO%aei=wg2PTNO0=J1D)-)4;uIVGT)jmPY)V7oL#2SG<@y0praCn6S*?OBW3O66M!A7X;RhP_8mr!G43hs&W0w5SGr&wX3}n0Qq0M=FjGKUu~58XNokf;KoXRF{M+Dm5%%FP;R~=IPibf1 z0PfVADM`QH06qLoeJhZ3zTLP-_u9LO;f}Y6s~sugp3Wmg?7X@)%tUIWlF|eXls#3aK>eJAJn$Q56{hoW&SV)-Qbi}CM#d?q>t|7+XWV+4Go-v8l8N54&AK=I=B?;cyM6fY{n zys7(I5scv<2frYG+JBdL@z9sV%)lo^|KKec;|~UtTj(z_^0frVur*c<$M|S$8$g23 zkLLhV=#9G}fvxf1AddBkBapfHH;OCnEM~yG-M! zd?KT&lxb{CF1aTtGG41nV4`dim>^pSG(F2dPmYQZ=YgpXfHY4}tLC!jn4qNH8u%>M zVwsu!;sts;C5@M6y)c8TvjaOaZl-kFEE1hUogio|V=HD>zeqXB7Rv61G|p$6AcMK= sZQ_YJm6Y6EGmU?my9DF-_WTfyf1Q66GE1(7H(U!qKk>3_K^hYO0>JlC@c;k- delta 1244 zcmaKrUrbYX6vywmw_w?A?L|OJwe7Epmtrjg5n*#H+*`0k6NXL@oQOc7f2blY;M|s| zV^Ojg+&G!pi-`~VV2qLYi%yqm;>)tR%s<(dxu?CECHhcfVlsSi=azPV9@tI#x#xV( z_x{eg{r&Dj#`+>-oxdyL_tNI8rdcp=e{X1b;DgsP{7k`+4Ciq{=_@h`%G>gB01=-? zD)5@J3QrdgKr=ooJ_9W{vmygJ9w`|oJ}GG?`bysp5z%7rCnoJb$r_WGsDXY|3F7Y#KOU}VFU@Pm@>jkHj&@tV_=+xD z_Mz8t#u5HoH=Z$P^-l`Jnh=uban`wSRl8M?nTbi8#a+y#3yMZbzOU?R&qoQ`5|T38~mkf7+?n3vR7yn2NAp!yN< z;`*jSqoF3?@mf2+T5q&#^lc(0eL>LqyzdTBlJf7N9sbcDg>G!9p?&7>*Yt=~cvx$A z3+re=-ch&J@P4r|K(3!RrpXnqcgye&#sY5W#F>Cf@fC`9^8106BJ9M+E$84}JgI#K zyU?yTQF(`62c3LcUk)VA1&!16G}uAh()ua!+tviJu5B-Iw(aZX8WU+Jm4qf}pmbsP z*3bWuASX5Brcfuz5|a!kZ9F;WLN`3wO%#n|5y>u+JsJOAkB^3v@V~aj9;4xAY}}S! zbV|%*ENJw~F8H6eKWvLaKd;~Zn+W}A?O>GDblh165zKUbN4(knhb7`MGphy(k7Ti- ztILD;cAuqEvgbN+ZSOA-;eYnV3+Xnr|Dgnf*bu3LLEaZx0TAbhhA#q)q9f{nI5tF| zLkz29dm(`*VlGJHg_ye}xyGakVJpx}TN3msfN}tTjfHFnZ8F7MJR%e5eh~ff>EbA5 z#;a5cOq5Lm6ZqZupa?PUPqqS#@zepep!^UMlre_}9B$X7P%&9@&EF1{lL5>3T@v<@6)si3ydI%M(o$Kc2V*BRDtN ZM{#Cy1Ei*%QzxBMKtJ&-=akeZ{sjn~RVx4h From a89206157a0225da2f88c3961dc80c75d5d7c1cd Mon Sep 17 00:00:00 2001 From: Chris Gundlach Date: Fri, 29 Jul 2022 09:42:32 -0500 Subject: [PATCH 5/8] removed kv test --- tests/nested_container_kv_test.py | 392 ------------------------------ 1 file changed, 392 deletions(-) delete mode 100755 tests/nested_container_kv_test.py diff --git a/tests/nested_container_kv_test.py b/tests/nested_container_kv_test.py deleted file mode 100755 index 14a6e88045..0000000000 --- a/tests/nested_container_kv_test.py +++ /dev/null @@ -1,392 +0,0 @@ -#!/usr/bin/env python3 - -from testUtils import Account -from testUtils import Utils -from testUtils import ReturnType -from Cluster import Cluster -from WalletMgr import WalletMgr -from TestHelper import TestHelper -import json - -############################################################### -# Nested_container_kv_test -# -# Load nested container contracts for kv table -# Verifies nested container for table below -# -############################################################### -# | set | vector | optional | map | pair | tuple | -#--------------------------------------------------------------- -#set | X | X | X | X | X | X | -#--------------------------------------------------------------- -#vector | X | X | X | X | X | X | -#--------------------------------------------------------------- -#optional | X | X | X | X | X | X | -#--------------------------------------------------------------- -#map | X | X | X | X | X | X | -#--------------------------------------------------------------- -#pair | X | X | X | X | X | X | -#--------------------------------------------------------------- -#tuple | X | X | X | X | X | X | -#--------------------------------------------------------------- -################################################################ - -Print=Utils.Print -errorExit=Utils.errorExit - -args=TestHelper.parse_args({"-p","-n","-d","-s","--nodes-file","--seed" - ,"--dump-error-details","-v","--leave-running" - ,"--clean-run","--keep-logs"}) - -pnodes=args.p -topo=args.s -delay=args.d -total_nodes = pnodes if args.n < pnodes else args.n -debug=args.v -nodesFile=args.nodes_file -dontLaunch=nodesFile is not None -seed=args.seed -dontKill=args.leave_running -dumpErrorDetails=args.dump_error_details -killAll=args.clean_run -keepLogs=args.keep_logs - -killWallet=not dontKill -killEosInstances=not dontKill -if nodesFile is not None: - killEosInstances=False - -Utils.Debug=debug -testSuccessful=False - -cluster=Cluster(walletd=True) - -walletMgr=WalletMgr(True) -EOSIO_ACCT_PRIVATE_DEFAULT_KEY = "5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3" -EOSIO_ACCT_PUBLIC_DEFAULT_KEY = "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" -contractDir='unittests/test-contracts/nested_container_kv' -wasmFile='nested_container_kv.wasm' -abiFile='nested_container_kv.abi' -kvcontractDir='unittests/contracts' -kvWasmFile='kv_bios.wasm' -kvAbiFile='kv_bios.abi' - -def create_action(action, data, contract_account, usr): - cmdArr= [Utils.EosClientPath, '-v', 'push', 'action', contract_account, action, data, '-p', usr+'@active'] - clargs = node.eosClientArgs().split() - for x in clargs[::-1]: - cmdArr.insert(1, x) - result = Utils.checkOutput(cmdArr, ignoreError=False) - Print("result= ", result) - -try: - cluster.killall(allInstances=False) - cluster.cleanup() - - Print ("producing nodes: %s, non-producing nodes: %d, topology: %s, delay between nodes launch(seconds): %d" % - (pnodes, total_nodes-pnodes, topo, delay)) - - Print("Stand up cluster") - if cluster.launch(pnodes=1, totalNodes=1) is False: - errorExit("Failed to stand up eos cluster.") - - Print ("Wait for Cluster stabilization") - # wait for cluster to start producing blocks - if not cluster.waitOnClusterBlockNumSync(3): - errorExit("Cluster never stabilized") - - Print("Creating kv account") - kvacct = Account('nestcontn2kv') - kvacct.ownerPublicKey = EOSIO_ACCT_PUBLIC_DEFAULT_KEY - kvacct.activePublicKey = EOSIO_ACCT_PUBLIC_DEFAULT_KEY - cluster.createAccountAndVerify(kvacct, cluster.eosioAccount, buyRAM=7000000) - Print("Creating user account") - useracct = Account('alice') - useracct.ownerPublicKey = EOSIO_ACCT_PUBLIC_DEFAULT_KEY - useracct.activePublicKey = EOSIO_ACCT_PUBLIC_DEFAULT_KEY - cluster.createAccountAndVerify(useracct, cluster.eosioAccount, buyRAM=7000000) - - Print("Validating accounts") - cluster.validateAccounts([kvacct, useracct]) - - node = cluster.getNode() - - Print("Setting kv settings account privileged") - node.pushMessage(cluster.eosioAccount.name, 'setpriv', '["nestcontn2kv", 1]', '-p eosio@active') - node.publishContract(cluster.eosioAccount, kvcontractDir, kvWasmFile, kvAbiFile, waitForTransBlock=True) - node.pushMessage(cluster.eosioAccount.name, 'ramkvlimits', '[2024, 2024, 2024]', '-p eosio@active') - - Print("Loading nested container kv contract") - node.publishContract(kvacct, contractDir, wasmFile, abiFile, waitForTransBlock=True) - - Print("Test action for set< set< uint16_t >>") - create_action('setstst', '[1, [[10, 10], [3], [400, 500, 600]]]', 'nestcontn2kv', 'alice') - - Print("Test action for set< vector< uint16_t >>") - create_action('setstv', '[1, [[16, 26], [36], [36], [46, 506, 606]]]', 'nestcontn2kv', 'alice') - - Print("Test action for set< optional< uint16_t >>") - create_action('setsto', '[1, [null, null, 500]]', 'nestcontn2kv', 'alice') - - Print("Test action for set< map< uint16_t, uint16_t >>") - create_action('setstm', '[1, [[{"key":30,"value":300},{"key":30,"value":300}],[{"key":60,"value":600},{"key":60,"value":600}]]]', 'nestcontn2kv', 'alice') - - Print("Test action for set< pair< uint16_t, uint16_t >>") - create_action('setstp', '[1, [{"key": 69, "value": 129}, {"key": 69, "value": 129}]]', 'nestcontn2kv', 'alice') - - Print("Test action for set< tuple< uint16_t, uint16_t >>") - create_action('setstt', '[1, [[1,2],[36,46], [56,66]]]', 'nestcontn2kv', 'alice') - - - Print("Test action for vector< set< uint16_t >>") - create_action('setvst', '[1, [[10, 10], [3], [400, 500, 600]]]', 'nestcontn2kv', 'alice') - - Print("Test action for vector< vector< uint16_t >>") - create_action('setvv', '[1, [[16, 26], [36], [36], [46, 506, 606]]]', 'nestcontn2kv', 'alice') - - Print("Test action for vector< optional< uint16_t >>") - create_action('setvo', '[1,[null, null, 500]]', 'nestcontn2kv', 'alice') - - Print("Test action for vector< map< uint16_t, uint16_t >>") - create_action('setvm', '[1, [[{"key": 30, "value": 300}, {"key": 30, "value": 300}], [{"key": 60, "value": 600}, {"key": 60, "value": 600}]]]' - , 'nestcontn2kv', 'alice') - - Print("Test action for vector< pair< uint16_t, uint16_t >>") - create_action('setvp', '[1, [{"key": 69, "value": 129}, {"key": 69, "value": 129}]]', 'nestcontn2kv', 'alice') - - Print("Test action for vector< tuple< uint16_t, uint16_t >>") - create_action('setvt', '[1, [[10,20],[30,40], [50,60]]]', 'nestcontn2kv', 'alice') - - - Print("Test action for optional< set< uint16_t >>") - create_action('setost', '[1, [10, 10, 3]]', 'nestcontn2kv', 'alice') - create_action('setost', '[2, null]', 'nestcontn2kv', 'alice') - - Print("Test action for optional< vector< uint16_t >>") - create_action('setov', '[1, [46, 506, 606]]', 'nestcontn2kv', 'alice') - create_action('setov', '[2, null]', 'nestcontn2kv', 'alice') - - Print("Test action for optional< optional< uint16_t >>") - create_action('setoo', '[1, 500]', 'nestcontn2kv', 'alice') - create_action('setoo', '[2, null]', 'nestcontn2kv', 'alice') - - Print("Test action for optional< map< uint16_t, uint16_t >>") - create_action('setom', '[1, [{"key": 10, "value": 1000}, {"key": 11,"value": 1001}] ]', 'nestcontn2kv', 'alice') - create_action('setom', '[2, null]', 'nestcontn2kv', 'alice') - - Print("Test action for optional< pair< uint16_t, uint16_t >>") - create_action('setop', '[1, {"key": 60, "value": 61}]', 'nestcontn2kv', 'alice') - create_action('setop', '[2, null]', 'nestcontn2kv', 'alice') - - Print("Test action for optional< tuple< uint16_t, uint16_t >>") - create_action('setot', '[1, [1001,2001]]', 'nestcontn2kv', 'alice') - create_action('setot', '[2, null]', 'nestcontn2kv', 'alice') - - - Print("Test action for map< set< uint16_t >>") - create_action('setmst', '[1, [{"key": 1,"value": [10, 10, 12, 16]}, {"key": 2, "value": [200, 300]} ]]', 'nestcontn2kv', 'alice') - - Print("Test action for map< vector< uint16_t >>") - create_action('setmv', '[1, [{"key": 1, "value": [10, 10, 12, 16]}, {"key": 2, "value": [200, 300]} ]]', 'nestcontn2kv', 'alice') - - Print("Test action for map< optional< uint16_t >>") - create_action('setmo', '[1, [{"key": 10, "value": 1000}, {"key": 11, "value": null}]]', 'nestcontn2kv', 'alice') - - Print("Test action for map< map< uint16_t, uint16_t >>") - create_action('setmm', '[1, [{"key": 10, "value": [{"key": 200, "value": 2000}, \ - {"key": 201, "value": 2001}] }, {"key": 11, "value": [{"key": 300, "value": 3000}, {"key": 301, "value": 3001}] } ]]', 'nestcontn2kv', 'alice') - - Print("Test action for map< pair< uint16_t, uint16_t >>") - create_action('setmp', '[1, [{"key": 36, "value": {"key": 300, "value": 301}}, {"key": 37, "value": {"key": 600, "value": 601}} ]]', 'nestcontn2kv', 'alice') - - Print("Test action for map< tuple< uint16_t, uint16_t >>") - create_action('setmt', '[1, [{"key":1,"value":[10,11]}, {"key":2,"value":[200,300]} ]]', 'nestcontn2kv', 'alice') - - - Print("Test action for pair< set< uint16_t >>") - create_action('setpst', '[1, {"key": 20, "value": [200, 200, 202]}]', 'nestcontn2kv', 'alice') - - Print("Test action for pair< vector< uint16_t >>") - create_action('setpv', '[1, {"key": 10, "value": [100, 100, 102]}]', 'nestcontn2kv', 'alice') - - Print("Test action for pair< optional< uint16_t >>") - create_action('setpo', '[1, {"key": 70, "value": 71}]', 'nestcontn2kv', 'alice') - create_action('setpo', '[2, {"key": 70, "value": null}]', 'nestcontn2kv', 'alice') - - Print("Test action for pair< map< uint16_t, uint16_t >>") - create_action('setpm', '[1, {"key": 6, "value": [{"key": 20, "value": 300}, {"key": 21,"value": 301}] }]', 'nestcontn2kv', 'alice') - - Print("Test action for pair< pair< uint16_t, uint16_t >>") - create_action('setpp', '[1, {"key": 30, "value": {"key": 301, "value": 302} }]', 'nestcontn2kv', 'alice') - - Print("Test action for pair< tuple< uint16_t, uint16_t >>") - create_action('setpt', '[1, {"key":10, "value":[100,101]}]', 'nestcontn2kv', 'alice') - - - Print("Test action for tuple< uint16_t, set< uint16_t >, set< uint16_t >>") - create_action('settst', '[1, [10,[21,31], [41,51,61]]]', 'nestcontn2kv', 'alice') - - Print("Test action for tuple< uint16_t, vector< uint16_t >, vector< uint16_t >") - create_action('settv', '[1, [16,[26,36], [46,506,606]]]', 'nestcontn2kv', 'alice') - - Print("Test action for tuple< optional< uint16_t >, optional< uint16_t >, optional< uint16_t > \ - , optional< uint16_t >, optional< uint16_t >>") - create_action('setto', '[1, [100, null, 200, null, 300]]', 'nestcontn2kv', 'alice') - create_action('setto', '[2, [null, null, 10, null, 20]]', 'nestcontn2kv', 'alice') - - Print("Test action for tuple< map< uint16_t, uint16_t >, map< uint16_t, uint16_t >>") - create_action('settm', '[1, [126, [{"key":10,"value":100},{"key":11,"value":101}], [{"key":80,"value":800},{"key":81,"value":9009}] ]]', 'nestcontn2kv', 'alice') - - Print("Test action for tuple< uint16_t, pair< uint16_t, uint16_t >, pair< uint16_t, uint16_t >>") - create_action('settp', '[1, [127, {"key":18, "value":28}, {"key":19, "value":29}]]', 'nestcontn2kv', 'alice') - - Print("Test action for tuple< tuple< uint16_t, uint16_t >, tuple< uint16_t, uint16_t >, tuple< uint16_t, uint16_t >>") - create_action('settt', '[1, [[1,2],[30,40], [50,60]]]', 'nestcontn2kv', 'alice') - - - Print("Test action for vector>") - create_action('setvos', '[1, [{"_count": 18, "_strID": "dumstr"}, null, {"_count": 19, "_strID": "dumstr"}]]', 'nestcontn2kv', 'alice') - - Print("Test action for pair>>") - create_action('setpvo', '[1,{"first": 183, "second":[100, null, 200]}]', 'nestcontn2kv', 'alice') - - cmd="get kv_table %s people2kv map.index" % kvacct.name - transaction = node.processCleosCmd(cmd, cmd, False, returnType=ReturnType.raw) - transaction_json = json.loads(transaction) - - assert "[[3], [10], [400, 500, 600]]" == str(transaction_json['rows'][0]['stst']), \ - 'Content of kv table set< set< uint16_t >> is not correct' - - assert "[[16, 26], [36], [46, 506, 606]]" == str(transaction_json['rows'][0]['stv']), \ - 'Content of kv table set< vector< uint16_t >> is not correct' - - assert "[None, 500]" == str(transaction_json['rows'][0]['sto']), 'Content of kv table set< optional< uint16_t >> is not correct' - - assert "[[{'key': 30, 'value': 300}], [{'key': 60, 'value': 600}]]" \ - == str(transaction_json['rows'][0]['stm']), 'Content of kv table set< map< uint16_t >> is not correct' - - assert "[{'key': 69, 'value': 129}]" == str(transaction_json['rows'][0]['stp']), \ - 'Content of kv table set< pair< uint16_t >> is not correct' - - assert "[{'field_0': 1, 'field_1': 2}, {'field_0': 36, 'field_1': 46}, {'field_0': 56, 'field_1': 66}]" == str(transaction_json['rows'][0]['stt']), \ - 'Content of kv table set< tuple< uint16_t, uint16_t >> is not correct' - - - - assert "[[10], [3], [400, 500, 600]]" == str(transaction_json['rows'][0]['vst']), \ - 'Content of kv table vector< set< uint16_t >> is not correct' - - assert "[[16, 26], [36], [36], [46, 506, 606]]" == str(transaction_json['rows'][0]['vv']), \ - 'Content of kv table vector< vector< uint16_t >> is not correct' - - assert "[None, None, 500]" == str(transaction_json['rows'][0]['vo']), \ - 'Content of kv table vector< optional< uint16_t >> is not correct' - - assert "[[{'key': 30, 'value': 300}], [{'key': 60, 'value': 600}]]" \ - == str(transaction_json['rows'][0]['vm']), 'Content of kv table vector< map< uint16_t >> is not correct' - - assert "[{'key': 69, 'value': 129}, {'key': 69, 'value': 129}]" == str(transaction_json['rows'][0]['vp']), \ - 'Content of kv table vector< pair< uint16_t >> is not correct' - - assert "[{'field_0': 10, 'field_1': 20}, {'field_0': 30, 'field_1': 40}, {'field_0': 50, 'field_1': 60}]" == str(transaction_json['rows'][0]['vt']), \ - 'Content of kv table vector< tuple< uint16_t, uint16_t >> is not correct' - - - assert "[3, 10]" == str(transaction_json['rows'][0]['ost']), 'Content of kv table optional< set< uint16_t >> is not correct' - assert "None" == str(transaction_json['rows'][1]['ost']), 'Content of kv table optional< set< uint16_t >> is not correct' - - assert "[46, 506, 606]" == str(transaction_json['rows'][0]['ov']), 'Content of kv table optional< vector< uint16_t >> is not correct' - assert "None" == str(transaction_json['rows'][1]['ov']), 'Content of kv table optional< set< uint16_t >> is not correct' - - assert "500" == str(transaction_json['rows'][0]['oo']), 'Content of kv table optional< optional< uint16_t >> is not correct' - assert "None" == str(transaction_json['rows'][1]['oo']), 'Content of kv table optional< set< uint16_t >> is not correct' - - assert "[{'key': 10, 'value': 1000}, {'key': 11, 'value': 1001}]" \ - == str(transaction_json['rows'][0]['om']), 'Content of kv table optional< map< uint16_t >> is not correct' - assert "None" == str(transaction_json['rows'][1]['om']), 'Content of kv table optional< set< uint16_t >> is not correct' - - assert "{'key': 60, 'value': 61}" == str(transaction_json['rows'][0]['op']), \ - 'Content of kv table optional< pair< uint16_t >> is not correct' - assert "None" == str(transaction_json['rows'][1]['op']), 'Content of kv table optional< set< uint16_t >> is not correct' - - assert "{'field_0': 1001, 'field_1': 2001}" == str(transaction_json['rows'][0]['ot']), 'Content of kv table optional< tuple< uint16_t, uint16_t >> is not correct' - assert "None" == str(transaction_json['rows'][1]['ot']), 'Content of kv table optional< tuple< uint16_t, uint16_t >> is not correct' - - - assert "[{'key': 1, 'value': [10, 12, 16]}, {'key': 2, 'value': [200, 300]}]" \ - == str(transaction_json['rows'][0]['mst']), 'Content of kv table map< set< uint16_t >> is not correct' - - assert "[{'key': 1, 'value': [10, 10, 12, 16]}, {'key': 2, 'value': [200, 300]}]" \ - == str(transaction_json['rows'][0]['mv']), 'Content of kv table map< vector< uint16_t >> is not correct' - - assert "[{'key': 10, 'value': 1000}, {'key': 11, 'value': None}]" == \ - str(transaction_json['rows'][0]['mo']), 'Content of kv table map< optional< uint16_t >> is not correct' - - assert "[{'key': 10, 'value': [{'key': 200, 'value': 2000}, {'key': 201, 'value': 2001}]}, {'key': 11, 'value': [{'key': 300, 'value': 3000}, {'key': 301, 'value': 3001}]}]" \ - == str(transaction_json['rows'][0]['mm']), 'Content of kv table map< map< uint16_t >> is not correct' - - assert "[{'key': 36, 'value': {'key': 300, 'value': 301}}, {'key': 37, 'value': {'key': 600, 'value': 601}}]"\ - == str(transaction_json['rows'][0]['mp']), 'Content of kv table map< pair< uint16_t >> is not correct' - - assert "[{'key': 1, 'value': {'field_0': 10, 'field_1': 11}}, {'key': 2, 'value': {'field_0': 200, 'field_1': 300}}]"\ - == str(transaction_json['rows'][0]['mt']), 'Content of kv table map< uint16_t, tuple< uint16_t, uint16_t >> is not correct' - - - assert "{'key': 20, 'value': [200, 202]}" == str(transaction_json['rows'][0]['pst']), \ - 'Content of kv table pair< set< uint16_t >> is not correct' - - assert "{'key': 10, 'value': [100, 100, 102]}" == str(transaction_json['rows'][0]['pv']), \ - 'Content of kv table pair< vector< uint16_t >> is not correct' - - assert "{'key': 70, 'value': 71}" == str(transaction_json['rows'][0]['po']), \ - 'Content of kv table pair< optional< uint16_t >> is not correct' - - assert "{'key': 70, 'value': None}" == str(transaction_json['rows'][1]['po']), \ - 'Content of kv table pair< optional< uint16_t >> is not correct' - - assert "{'key': 6, 'value': [{'key': 20, 'value': 300}, {'key': 21, 'value': 301}]}" \ - == str(transaction_json['rows'][0]['pm']), 'Content of kv table pair< map< uint16_t >> is not correct' - - assert "{'key': 30, 'value': {'key': 301, 'value': 302}}" == str(transaction_json['rows'][0]['pp']),\ - 'Content of kv table pair< pair< uint16_t >> is not correct' - - assert "{'key': 10, 'value': {'field_0': 100, 'field_1': 101}}"\ - == str(transaction_json['rows'][0]['pt']), 'Content of kv table pair< uint16_t, tuple< uint16_t, uint16_t >> is not correct' - - - assert "{'field_0': 10, 'field_1': [21, 31], 'field_2': [41, 51, 61]}" == str(transaction_json['rows'][0]['tst']), \ - 'Content of kv table tuple< set< uint16_t >> is not correct' - - assert "{'field_0': 16, 'field_1': [26, 36], 'field_2': [46, 506, 606]}" == str(transaction_json['rows'][0]['tv']), \ - 'Content of kv table tuple< vector< uint16_t >> is not correct' - - assert "{'field_0': 100, 'field_1': None, 'field_2': 200, 'field_3': None, 'field_4': 300}" == str(transaction_json['rows'][0]['to']), \ - 'Content of kv table tuple< optional< uint16_t >> is not correct' - - assert "{'field_0': None, 'field_1': None, 'field_2': 10, 'field_3': None, 'field_4': 20}" == str(transaction_json['rows'][1]['to']), \ - 'Content of kv table tuple< optional< uint16_t >> is not correct' - - assert "{'field_0': 126, 'field_1': [{'key': 10, 'value': 100}, {'key': 11, 'value': 101}], 'field_2': [{'key': 80, 'value': 800}, {'key': 81, 'value': 9009}]}" \ - == str(transaction_json['rows'][0]['tm']), 'Content of kv table pair< map< uint16_t, uint16_t >> is not correct' - - assert "{'field_0': 127, 'field_1': {'key': 18, 'value': 28}, 'field_2': {'key': 19, 'value': 29}}" == str(transaction_json['rows'][0]['tp']),\ - 'Content of kv table tuple< pair< uint16_t, uint16_t >> is not correct' - - assert "{'field_0': {'field_0': 1, 'field_1': 2}, 'field_1': {'field_0': 30, 'field_1': 40}, 'field_2': {'field_0': 50, 'field_1': 60}}"\ - == str(transaction_json['rows'][0]['tt']), 'Content of kv table tuple< tuple< uint16_t, uint16_t >, ...> is not correct' - - - assert "[{'_count': 18, '_strID': 'dumstr'}, None, {'_count': 19, '_strID': 'dumstr'}]" == str(transaction_json['rows'][0]['vos']), \ - "Content of kv table vector> is not correct" - - assert "{'first': 183, 'second': [100, None, 200]}" == str(transaction_json['rows'][0]['pvo']), \ - "Content of kv table pair>> is not correct" - - testSuccessful=True - - assert testSuccessful - -finally: - TestHelper.shutdown(cluster, walletMgr, testSuccessful, killEosInstances, killWallet) - -exit(0) \ No newline at end of file From b73c365e6cd273223b9b88ef51253284c560af12 Mon Sep 17 00:00:00 2001 From: Chris Gundlach Date: Mon, 1 Aug 2022 08:10:03 -0500 Subject: [PATCH 6/8] added transaction trace plugin --- tests/nested_container_multi_index_test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/nested_container_multi_index_test.py b/tests/nested_container_multi_index_test.py index ccc4f027e5..52f49b2515 100755 --- a/tests/nested_container_multi_index_test.py +++ b/tests/nested_container_multi_index_test.py @@ -84,7 +84,7 @@ def create_action(action, data, contract_account, usr): (pnodes, total_nodes-pnodes, topo, delay)) Print("Stand up cluster") - if cluster.launch(pnodes=1, totalNodes=1) is False: + if cluster.launch(pnodes=1, totalNodes=1, extraNodeosArgs=" --plugin eosio::trace_api_plugin --trace-no-abis ") is False: errorExit("Failed to stand up eos cluster.") Print ("Wait for Cluster stabilization") From 3509fb3a66ce1bb7e36b56b0a2463be4d28fe543 Mon Sep 17 00:00:00 2001 From: Chris Gundlach Date: Wed, 3 Aug 2022 10:10:39 -0500 Subject: [PATCH 7/8] GH-524 cleaned up whitespace --- .../nested_container_multi_index.cpp | 31 +++++++++---------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/unittests/test-contracts/nested_container_multi_index/nested_container_multi_index.cpp b/unittests/test-contracts/nested_container_multi_index/nested_container_multi_index.cpp index 07092ce94f..2b9920d4b6 100644 --- a/unittests/test-contracts/nested_container_multi_index/nested_container_multi_index.cpp +++ b/unittests/test-contracts/nested_container_multi_index/nested_container_multi_index.cpp @@ -24,23 +24,20 @@ using namespace eosio; using namespace std; #define SETCONTAINERVAL(x) do { \ - require_auth(user); \ - psninfoindex2 tblIndex(get_self(), get_first_receiver().value); \ - auto iter = tblIndex.find(user.value); \ - if (iter == tblIndex.end()) \ - { \ - tblIndex.emplace(user, [&](auto &row) { \ - row.key = user; \ - row.x = x; \ - }); \ - } \ - else \ - { \ - tblIndex.modify(iter, user, [&]( auto& row ) { \ - row.x = x; \ - }); \ - } \ - }while(0) + require_auth(user); \ + psninfoindex2 tblIndex(get_self(), get_first_receiver().value); \ + auto iter = tblIndex.find(user.value); \ + if (iter == tblIndex.end()) { \ + tblIndex.emplace(user, [&](auto &row) { \ + row.key = user; \ + row.x = x; \ + }); \ + } else { \ + tblIndex.modify(iter, user, [&]( auto& row ) { \ + row.x = x; \ + }); \ + } \ + } while(0) struct mystruct { From 9f35958d1e6068a31bc63191b45af78841c6065b Mon Sep 17 00:00:00 2001 From: Chris Gundlach Date: Wed, 3 Aug 2022 10:16:00 -0500 Subject: [PATCH 8/8] added check for testSuccessful --- tests/nested_container_multi_index_test.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/nested_container_multi_index_test.py b/tests/nested_container_multi_index_test.py index 52f49b2515..0b86718a86 100755 --- a/tests/nested_container_multi_index_test.py +++ b/tests/nested_container_multi_index_test.py @@ -390,4 +390,7 @@ def create_action(action, data, contract_account, usr): finally: TestHelper.shutdown(cluster, walletMgr, testSuccessful, killEosInstances, killWallet) -exit(0) \ No newline at end of file +if testSuccessful: + exit(0) +else: + exit(-1) \ No newline at end of file