332 testcase(
"unsteppedThenSteppedWithNFTs");
341 auto const USD1 = gw1[
"USD"];
342 auto const USD2 = gw2[
"USD"];
344 env.
fund(
XRP(1000), gw1, gw2, bob);
351 params[jss::account] = bob.human();
352 auto resp = env.
rpc(
"json",
"account_objects",
to_string(params));
353 BEAST_EXPECT(!resp.isMember(jss::marker));
354 BEAST_EXPECT(resp[jss::result][jss::account_objects].size() == 0);
357 params[jss::limit] = 1;
358 resp = env.
rpc(
"json",
"account_objects",
to_string(params));
359 BEAST_EXPECT(!resp.isMember(jss::marker));
360 BEAST_EXPECT(resp[jss::result][jss::account_objects].size() == 0);
372 params[jss::account] = bob.human();
373 auto resp = env.
rpc(
"json",
"account_objects",
to_string(params));
374 BEAST_EXPECT(!resp.isMember(jss::marker));
376 unpaged = resp[jss::result][jss::account_objects];
377 BEAST_EXPECT(unpaged.
size() == 1);
382 params[jss::account] = bob.human();
383 params[jss::type] = jss::nft_page;
384 auto resp = env.
rpc(
"json",
"account_objects",
to_string(params));
385 BEAST_EXPECT(!resp.isMember(jss::marker));
386 Json::Value& aobjs = resp[jss::result][jss::account_objects];
387 BEAST_EXPECT(aobjs.
size() == 1);
388 BEAST_EXPECT(aobjs[0u][sfLedgerEntryType.jsonName] == jss::NFTokenPage);
389 BEAST_EXPECT(aobjs[0u][sfNFTokens.jsonName].
size() == 1);
394 params[jss::account] = bob.human();
395 params[jss::limit] = 1;
398 Json::Value& aobjs = resp[jss::result][jss::account_objects];
399 BEAST_EXPECT(aobjs.
size() == 1);
400 auto& aobj = aobjs[0U];
401 BEAST_EXPECT(!resp[jss::result].isMember(jss::limit));
402 BEAST_EXPECT(!resp[jss::result].isMember(jss::marker));
404 BEAST_EXPECT(aobj == unpaged[0u]);
408 env.
trust(USD1(1000), bob);
409 env.
trust(USD2(1000), bob);
411 env(
pay(gw1, bob, USD1(1000)));
412 env(
pay(gw2, bob, USD2(1000)));
421 params[jss::account] = bob.human();
422 auto resp = env.
rpc(
"json",
"account_objects",
to_string(params));
423 BEAST_EXPECT(!resp.isMember(jss::marker));
425 unpaged = resp[jss::result][jss::account_objects];
426 BEAST_EXPECT(unpaged.
size() == 5);
431 params[jss::account] = bob.human();
432 params[jss::type] = jss::nft_page;
433 auto resp = env.
rpc(
"json",
"account_objects",
to_string(params));
434 BEAST_EXPECT(!resp.isMember(jss::marker));
435 Json::Value& aobjs = resp[jss::result][jss::account_objects];
436 BEAST_EXPECT(aobjs.
size() == 1);
437 BEAST_EXPECT(aobjs[0u][sfLedgerEntryType.jsonName] == jss::NFTokenPage);
438 BEAST_EXPECT(aobjs[0u][sfNFTokens.jsonName].
size() == 1);
443 params[jss::account] = bob.human();
444 params[jss::limit] = 1;
445 for (
int i = 0; i < 5; ++i)
448 Json::Value& aobjs = resp[jss::result][jss::account_objects];
449 BEAST_EXPECT(aobjs.
size() == 1);
450 auto& aobj = aobjs[0U];
453 BEAST_EXPECT(resp[jss::result][jss::limit] == 1);
454 BEAST_EXPECT(resp[jss::result].isMember(jss::marker));
458 BEAST_EXPECT(!resp[jss::result].isMember(jss::limit));
459 BEAST_EXPECT(!resp[jss::result].isMember(jss::marker));
462 BEAST_EXPECT(aobj == unpaged[i]);
464 params[jss::marker] = resp[jss::result][jss::marker];
469 for (
int i = 0; i < 32; ++i)
477 params[jss::account] = bob.human();
478 auto resp = env.
rpc(
"json",
"account_objects",
to_string(params));
479 BEAST_EXPECT(!resp.isMember(jss::marker));
481 unpaged = resp[jss::result][jss::account_objects];
482 BEAST_EXPECT(unpaged.
size() == 6);
487 params[jss::account] = bob.human();
488 params[jss::type] = jss::nft_page;
489 auto resp = env.
rpc(
"json",
"account_objects",
to_string(params));
490 BEAST_EXPECT(!resp.isMember(jss::marker));
491 Json::Value const& aobjs = resp[jss::result][jss::account_objects];
492 BEAST_EXPECT(aobjs.
size() == 2);
497 params[jss::account] = bob.human();
498 params[jss::limit] = 1;
499 for (
int i = 0; i < 6; ++i)
502 Json::Value& aobjs = resp[jss::result][jss::account_objects];
503 BEAST_EXPECT(aobjs.
size() == 1);
504 auto& aobj = aobjs[0U];
507 BEAST_EXPECT(resp[jss::result][jss::limit] == 1);
508 BEAST_EXPECT(resp[jss::result].isMember(jss::marker));
512 BEAST_EXPECT(!resp[jss::result].isMember(jss::limit));
513 BEAST_EXPECT(!resp[jss::result].isMember(jss::marker));
516 BEAST_EXPECT(aobj == unpaged[i]);
518 params[jss::marker] = resp[jss::result][jss::marker];
534 auto const USD = gw[
"USD"];
536 auto const features =
538 Env env(*
this, features);
541 auto acctObjs = [&env](
549 params[jss::type] = *type;
551 params[jss::limit] = *limit;
553 params[jss::marker] = *marker;
554 params[jss::ledger_index] =
"validated";
555 return env.
rpc(
"json",
"account_objects",
to_string(params));
559 auto acctObjsIsSize = [](
Json::Value const& resp,
unsigned size) {
560 return resp[jss::result][jss::account_objects].
isArray() &&
561 (resp[jss::result][jss::account_objects].
size() == size);
565 auto acctObjsTypeIsInvalid = [](
Json::Value const& resp) {
566 return resp[jss::result].
isMember(jss::error) &&
567 resp[jss::result][jss::error_message] ==
"Invalid field \'type\'.";
570 env.
fund(
XRP(10000), gw, alice);
575 BEAST_EXPECT(acctObjsIsSize(acctObjs(gw, jss::account), 0));
576 BEAST_EXPECT(acctObjsIsSize(acctObjs(gw, jss::check), 0));
577 BEAST_EXPECT(acctObjsIsSize(acctObjs(gw, jss::deposit_preauth), 0));
578 BEAST_EXPECT(acctObjsIsSize(acctObjs(gw, jss::escrow), 0));
579 BEAST_EXPECT(acctObjsIsSize(acctObjs(gw, jss::nft_page), 0));
580 BEAST_EXPECT(acctObjsIsSize(acctObjs(gw, jss::offer), 0));
581 BEAST_EXPECT(acctObjsIsSize(acctObjs(gw, jss::payment_channel), 0));
582 BEAST_EXPECT(acctObjsIsSize(acctObjs(gw, jss::signer_list), 0));
583 BEAST_EXPECT(acctObjsIsSize(acctObjs(gw, jss::state), 0));
584 BEAST_EXPECT(acctObjsIsSize(acctObjs(gw, jss::ticket), 0));
585 BEAST_EXPECT(acctObjsIsSize(acctObjs(gw, jss::amm), 0));
586 BEAST_EXPECT(acctObjsIsSize(acctObjs(gw, jss::did), 0));
587 BEAST_EXPECT(acctObjsIsSize(acctObjs(gw, jss::permissioned_domain), 0));
590 BEAST_EXPECT(acctObjsTypeIsInvalid(acctObjs(gw, jss::amendments)));
591 BEAST_EXPECT(acctObjsTypeIsInvalid(acctObjs(gw, jss::directory)));
592 BEAST_EXPECT(acctObjsTypeIsInvalid(acctObjs(gw, jss::fee)));
593 BEAST_EXPECT(acctObjsTypeIsInvalid(acctObjs(gw, jss::hashes)));
594 BEAST_EXPECT(acctObjsTypeIsInvalid(acctObjs(gw, jss::NegativeUNL)));
602 Json::Value const resp = acctObjs(gw, jss::nft_page);
603 BEAST_EXPECT(acctObjsIsSize(resp, 1));
605 auto const& nftPage = resp[jss::result][jss::account_objects][0u];
606 BEAST_EXPECT(nftPage[sfNFTokens.jsonName].size() == 1);
608 nftPage[sfNFTokens.jsonName][0u][sfNFToken.jsonName][sfNFTokenID.jsonName] ==
613 env.
trust(USD(1000), alice);
615 env(
pay(gw, alice, USD(5)));
620 BEAST_EXPECT(acctObjsIsSize(resp, 1));
622 auto const& state = resp[jss::result][jss::account_objects][0u];
623 BEAST_EXPECT(state[sfBalance.jsonName][jss::value].asInt() == -5);
624 BEAST_EXPECT(state[sfHighLimit.jsonName][jss::value].asUInt() == 1000);
632 BEAST_EXPECT(acctObjsIsSize(resp, 1));
634 auto const& check = resp[jss::result][jss::account_objects][0u];
635 BEAST_EXPECT(check[sfAccount.jsonName] == gw.human());
636 BEAST_EXPECT(check[sfDestination.jsonName] == alice.human());
637 BEAST_EXPECT(check[sfSendMax.jsonName][jss::value].asUInt() == 10);
644 Json::Value const resp = acctObjs(gw, jss::deposit_preauth);
645 BEAST_EXPECT(acctObjsIsSize(resp, 1));
647 auto const& preauth = resp[jss::result][jss::account_objects][0u];
648 BEAST_EXPECT(preauth[sfAccount.jsonName] == gw.human());
649 BEAST_EXPECT(preauth[sfAuthorize.jsonName] == alice.human());
654 jvEscrow[jss::TransactionType] = jss::EscrowCreate;
655 jvEscrow[jss::Account] = gw.human();
656 jvEscrow[jss::Destination] = gw.human();
664 Json::Value const resp = acctObjs(gw, jss::escrow);
665 BEAST_EXPECT(acctObjsIsSize(resp, 1));
667 auto const& escrow = resp[jss::result][jss::account_objects][0u];
668 BEAST_EXPECT(escrow[sfAccount.jsonName] == gw.human());
669 BEAST_EXPECT(escrow[sfDestination.jsonName] == gw.human());
670 BEAST_EXPECT(escrow[sfAmount.jsonName].asUInt() == 100'000'000);
683 Json::Value const resp = acctObjs(gw, jss::permissioned_domain);
684 BEAST_EXPECT(acctObjsIsSize(resp, 1));
686 auto const& permissionedDomain = resp[jss::result][jss::account_objects][0u];
688 permissionedDomain.isMember(jss::Owner) &&
689 (permissionedDomain[jss::Owner] == gw.human()));
690 bool const check1 = BEAST_EXPECT(
691 permissionedDomain.isMember(jss::AcceptedCredentials) &&
692 permissionedDomain[jss::AcceptedCredentials].isArray() &&
693 (permissionedDomain[jss::AcceptedCredentials].size() == 1) &&
694 (permissionedDomain[jss::AcceptedCredentials][0u].isMember(jss::Credential)));
698 auto const& credential =
699 permissionedDomain[jss::AcceptedCredentials][0u][jss::Credential];
701 credential.isMember(sfIssuer.jsonName) &&
702 (credential[sfIssuer.jsonName] == issuer.
human()));
704 credential.isMember(sfCredentialType.jsonName) &&
705 (credential[sfCredentialType.jsonName] ==
strHex(credentialType1)));
715 auto scEnvAcctObjs = [&](
Account const& acct,
char const* type) {
717 params[jss::account] = acct.
human();
718 params[jss::type] = type;
719 params[jss::ledger_index] =
"validated";
720 return scEnv.
rpc(
"json",
"account_objects",
to_string(params));
725 BEAST_EXPECT(acctObjsIsSize(resp, 1));
726 auto const& acct_bridge = resp[jss::result][jss::account_objects][0u];
728 BEAST_EXPECT(acct_bridge[sfLedgerEntryType.getJsonName()] ==
"Bridge");
729 BEAST_EXPECT(acct_bridge[sfXChainClaimID.getJsonName()].asUInt() == 0);
730 BEAST_EXPECT(acct_bridge[sfXChainAccountClaimCount.getJsonName()].asUInt() == 0);
731 BEAST_EXPECT(acct_bridge[sfXChainAccountCreateCount.getJsonName()].asUInt() == 0);
732 BEAST_EXPECT(acct_bridge[sfMinAccountCreateAmount.getJsonName()].asUInt() == 20000000);
733 BEAST_EXPECT(acct_bridge[sfSignatureReward.getJsonName()].asUInt() == 1000000);
734 BEAST_EXPECT(acct_bridge[sfXChainBridge.getJsonName()] == x.
jvb);
748 auto scEnvAcctObjs = [&](
Account const& acct,
char const* type) {
750 params[jss::account] = acct.
human();
751 params[jss::type] = type;
752 params[jss::ledger_index] =
"validated";
753 return scEnv.
rpc(
"json",
"account_objects",
to_string(params));
759 BEAST_EXPECT(acctObjsIsSize(resp, 1));
761 auto const& xchain_seq = resp[jss::result][jss::account_objects][0u];
762 BEAST_EXPECT(xchain_seq[sfAccount.jsonName] == x.
scAlice.
human());
763 BEAST_EXPECT(xchain_seq[sfXChainClaimID.getJsonName()].asUInt() == 1);
767 Json::Value const resp = scEnvAcctObjs(x.
scBob, jss::xchain_owned_claim_id);
768 BEAST_EXPECT(acctObjsIsSize(resp, 1));
770 auto const& xchain_seq = resp[jss::result][jss::account_objects][0u];
771 BEAST_EXPECT(xchain_seq[sfAccount.jsonName] == x.
scBob.
human());
772 BEAST_EXPECT(xchain_seq[sfXChainClaimID.getJsonName()].asUInt() == 2);
779 auto const amt =
XRP(1000);
799 auto scEnvAcctObjs = [&](
Account const& acct,
char const* type) {
801 params[jss::account] = acct.
human();
802 params[jss::type] = type;
803 params[jss::ledger_index] =
"validated";
804 return scEnv.
rpc(
"json",
"account_objects",
to_string(params));
810 scEnvAcctObjs(
Account::master, jss::xchain_owned_create_account_claim_id);
811 BEAST_EXPECT(acctObjsIsSize(resp, 1));
813 auto const& xchain_create_account_claim_id =
814 resp[jss::result][jss::account_objects][0u];
818 xchain_create_account_claim_id[sfXChainAccountCreateCount.getJsonName()]
829 BEAST_EXPECT(acctObjsIsSize(resp, 1));
831 auto const&
offer = resp[jss::result][jss::account_objects][0u];
832 BEAST_EXPECT(
offer[sfAccount.jsonName] == gw.human());
833 BEAST_EXPECT(
offer[sfTakerGets.jsonName].
asUInt() == 14'000'000);
834 BEAST_EXPECT(
offer[sfTakerPays.jsonName][jss::value].
asUInt() == 7);
840 jvPayChan[jss::TransactionType] = jss::PaymentChannelCreate;
841 jvPayChan[jss::Account] = gw.human();
842 jvPayChan[jss::Destination] = alice.human();
844 jvPayChan[sfSettleDelay.jsonName] = 24 * 60 * 60;
845 jvPayChan[sfPublicKey.jsonName] =
strHex(gw.pk().slice());
851 Json::Value const resp = acctObjs(gw, jss::payment_channel);
852 BEAST_EXPECT(acctObjsIsSize(resp, 1));
854 auto const& payChan = resp[jss::result][jss::account_objects][0u];
855 BEAST_EXPECT(payChan[sfAccount.jsonName] == gw.human());
856 BEAST_EXPECT(payChan[sfAmount.jsonName].asUInt() == 300'000'000);
857 BEAST_EXPECT(payChan[sfSettleDelay.jsonName].asUInt() == 24 * 60 * 60);
863 jvDID[jss::TransactionType] = jss::DIDSet;
864 jvDID[jss::Account] = gw.human();
872 BEAST_EXPECT(acctObjsIsSize(resp, 1));
874 auto const& did = resp[jss::result][jss::account_objects][0u];
875 BEAST_EXPECT(did[sfAccount.jsonName] == gw.human());
883 Json::Value const resp = acctObjs(gw, jss::signer_list);
884 BEAST_EXPECT(acctObjsIsSize(resp, 1));
886 auto const& signerList = resp[jss::result][jss::account_objects][0u];
887 BEAST_EXPECT(signerList[sfSignerQuorum.jsonName] == 6);
888 auto const& entry = signerList[sfSignerEntries.jsonName][0u][sfSignerEntry.jsonName];
889 BEAST_EXPECT(entry[sfAccount.jsonName] == alice.human());
890 BEAST_EXPECT(entry[sfSignerWeight.jsonName].
asUInt() == 7);
894 auto const seq = env.
seq(gw);
900 Json::Value const resp = acctObjs(gw, jss::ticket);
901 BEAST_EXPECT(acctObjsIsSize(resp, 1));
903 auto const& ticket = resp[jss::result][jss::account_objects][0u];
904 BEAST_EXPECT(ticket[sfAccount.jsonName] == gw.human());
905 BEAST_EXPECT(ticket[sfLedgerEntryType.jsonName] == jss::Ticket);
906 BEAST_EXPECT(ticket[sfTicketSequence.jsonName].asUInt() ==
seq + 1);
912 params[jss::account] = gw.human();
913 params[jss::deletion_blockers_only] =
true;
914 auto resp = env.
rpc(
"json",
"account_objects",
to_string(params));
920 jss::NFTokenPage.c_str(),
921 jss::RippleState.c_str(),
922 jss::PayChannel.c_str(),
923 jss::PermissionedDomain.c_str()};
931 if (BEAST_EXPECT(acctObjsIsSize(resp, expectedAccountObjects)))
933 auto const& aobjs = resp[jss::result][jss::account_objects];
935 gotLedgerTypes.
reserve(expectedAccountObjects);
938 gotLedgerTypes.
push_back(aobjs[i][
"LedgerEntryType"].asString());
941 BEAST_EXPECT(gotLedgerTypes == expectedLedgerTypes);
948 params[jss::account] = gw.human();
949 params[jss::deletion_blockers_only] =
true;
950 params[jss::type] = jss::escrow;
951 auto resp = env.
rpc(
"json",
"account_objects",
to_string(params));
953 if (BEAST_EXPECT(acctObjsIsSize(resp, 1u)))
955 auto const& aobjs = resp[jss::result][jss::account_objects];
956 BEAST_EXPECT(aobjs[0u][
"LedgerEntryType"] == jss::Escrow);
962 auto const objs = resp[jss::result][jss::account_objects];
963 for (
auto const& obj : resp[jss::result][jss::account_objects])
964 typesOut.push_back(obj[sfLedgerEntryType.fieldName].asString());
965 std::sort(typesOut.begin(), typesOut.end());
971 if (!acctObjsIsSize(resp, types.
size()))
974 getTypes(resp, typesOut);
975 return types == typesOut;
978 AMM amm(env, gw,
XRP(1'000), USD(1'000));
979 amm.deposit(alice, USD(1));
982 BEAST_EXPECT(
lines[jss::lines].size() == 3);
984 BEAST_EXPECT(acctObjsIsSize(acctObjs(amm.ammAccount(), jss::amm), 1));
986 auto resp = acctObjs(amm.ammAccount(),
std::nullopt, 2);
988 getTypes(resp, typesOut);
992 getTypes(resp, typesOut);
997 jss::RippleState.c_str(),
998 jss::RippleState.c_str(),
999 jss::RippleState.c_str()}));
1001 resp = acctObjs(amm.ammAccount(), jss::state, 10);
1002 BEAST_EXPECT(expectObjects(
1004 {jss::RippleState.c_str(), jss::RippleState.c_str(), jss::RippleState.c_str()}));
1006 BEAST_EXPECT(acctObjsIsSize(acctObjs(amm.ammAccount(), jss::offer), 0));
1008 BEAST_EXPECT(acctObjsIsSize(acctObjs(gw, jss::amm), 0));
1012 BEAST_EXPECT(acctObjsTypeIsInvalid(acctObjs(gw, jss::amendments)));
1013 BEAST_EXPECT(acctObjsTypeIsInvalid(acctObjs(gw, jss::directory)));
1014 BEAST_EXPECT(acctObjsTypeIsInvalid(acctObjs(gw, jss::fee)));
1015 BEAST_EXPECT(acctObjsTypeIsInvalid(acctObjs(gw, jss::hashes)));
1016 BEAST_EXPECT(acctObjsTypeIsInvalid(acctObjs(gw, jss::NegativeUNL)));
1020 for (
int d = 1'000'032; d >= 1'000'000; --d)
1027 BEAST_EXPECT(acctObjsIsSize(acctObjs(gw, jss::account), 0));
1175 using namespace jtx;
1181 env.
fund(
XRP(10000), alice, bob, carol);
1183 unsigned const accountObjectSize = 30;
1184 for (
unsigned i = 0; i < accountObjectSize; i++)
1187 for (
unsigned i = 0; i < 10; i++)
1192 unsigned const limit = 11;
1198 params[jss::account] = bob.human();
1199 params[jss::limit] = limit;
1200 params[jss::ledger_index] =
"validated";
1201 auto resp = env.
rpc(
"json",
"account_objects",
to_string(params));
1202 auto& accountObjects = resp[jss::result][jss::account_objects];
1203 marker = resp[jss::result][jss::marker];
1204 BEAST_EXPECT(!resp[jss::result].isMember(jss::error));
1205 BEAST_EXPECT(accountObjects.size() == limit);
1211 params[jss::account] = bob.human();
1212 params[jss::limit] = limit;
1213 params[jss::marker] = marker;
1214 params[jss::ledger_index] =
"validated";
1215 auto resp = env.
rpc(
"json",
"account_objects",
to_string(params));
1216 auto& accountObjects = resp[jss::result][jss::account_objects];
1217 marker = resp[jss::result][jss::marker];
1218 BEAST_EXPECT(!resp[jss::result].isMember(jss::error));
1219 BEAST_EXPECT(accountObjects.size() == limit);
1223 auto testInvalidMarker = [&](
std::string& marker) {
1225 params[jss::account] = bob.human();
1226 params[jss::limit] = limit;
1227 params[jss::ledger_index] = jss::validated;
1228 params[jss::marker] = marker;
1230 return resp[jss::result][jss::error_message] ==
"Invalid field \'marker\'.";
1233 auto const markerStr = marker.
asString();
1234 auto const& idx = markerStr.
find(
',');
1235 auto const dirIndex = markerStr.substr(0, idx);
1236 auto const entryIndex = markerStr.substr(idx + 1);
1241 BEAST_EXPECT(testInvalidMarker(s));
1248 BEAST_EXPECT(testInvalidMarker(s));
1256 BEAST_EXPECT(testInvalidMarker(s));
1264 s = dirIndex +
',' + s;
1265 BEAST_EXPECT(testInvalidMarker(s));
1272 BEAST_EXPECT(testInvalidMarker(s));
1281 params[jss::account] = bob.human();
1282 params[jss::limit] = limit;
1283 params[jss::marker] = s;
1284 params[jss::ledger_index] =
"validated";
1285 auto resp = env.
rpc(
"json",
"account_objects",
to_string(params));
1286 auto& accountObjects = resp[jss::result][jss::account_objects];
1287 BEAST_EXPECT(!resp[jss::result].isMember(jss::error));
1288 BEAST_EXPECT(accountObjects.size() == limit);
1295 BEAST_EXPECT(testInvalidMarker(s));
1302 BEAST_EXPECT(testInvalidMarker(s));
1309 params[jss::account] = bob.human();
1310 params[jss::limit] = limit;
1311 params[jss::marker] = marker;
1312 params[jss::ledger_index] =
"validated";
1313 auto resp = env.
rpc(
"json",
"account_objects",
to_string(params));
1314 auto& accountObjects = resp[jss::result][jss::account_objects];
1315 BEAST_EXPECT(!resp[jss::result].isMember(jss::error));
1316 BEAST_EXPECT(accountObjects.size() == accountObjectSize - (limit * 2));
1317 BEAST_EXPECT(!resp[jss::result].isMember(jss::marker));
1324 params[jss::account] = carol.human();
1325 params[jss::limit] = 10;
1326 params[jss::marker] =
"0," + entryIndex;
1327 params[jss::ledger_index] =
"validated";
1328 auto resp = env.
rpc(
"json",
"account_objects",
to_string(params));
1329 auto& accountObjects = resp[jss::result][jss::account_objects];
1330 BEAST_EXPECT(accountObjects.size() == 0);