diff --git a/contracts/identity/identity.hpp b/contracts/identity/identity.hpp index 99f35c04129d8534459b76f09518f5a1fd5fd7c1..1ef2fe23591c8208ec05dd4b721641acfc963c8d 100644 --- a/contracts/identity/identity.hpp +++ b/contracts/identity/identity.hpp @@ -211,13 +211,19 @@ namespace identity { certs_table certs( ident ); certrow row; bool ok = certs.primary_lower_bound(row, N(owner), 1, 0); + account_name owner = 0; while (ok && row.property == N(owner) && row.trusted) { if (sizeof(account_name) == row.data.size()) { account_name account = *reinterpret_cast(row.data.data()); if (ident == get_claimed_identity(account)) { if (is_trusted(row.certifier) ) { // the certifier is still trusted - return account; + if (!owner || owner == account) { + owner = account; + } else { + //contradiction found: different owners certified for the same identity + return 0; + } } else if (DeployToAccount == current_receiver()){ //the certifier is no longer trusted, need to unset the flag row.trusted = 0; @@ -230,6 +236,11 @@ namespace identity { // bad row - skip it } ok = certs.primary_upper_bound(row, row.property, row.trusted, row.certifier); + //ok = certs.next_primary(row, row); + } + if (owner) { + //owner found, no contradictions among certifications flaged as trusted + return owner; } // trusted certification not found // let's see if some of untrusted certifications became trusted @@ -243,7 +254,12 @@ namespace identity { row.trusted = 1; certs.store( row, 0 ); //assuming 0 means bill to the same account } - return account; + if (!owner || owner == account) { + owner = account; + } else { + //contradiction found: different owners certified for the same identity + return 0; + } } } else { // bad row - skip it @@ -251,8 +267,7 @@ namespace identity { ok = certs.primary_upper_bound(row, row.property, row.trusted, row.certifier); //ok = certs.next_primary(row, row); } - - return 0; + return owner; } static identity_name get_identity_for_account( account_name acnt ) { diff --git a/tests/wasm_tests/identity_tests.cpp b/tests/wasm_tests/identity_tests.cpp index 86ca564afef0286412dc41fbe5ad1771cdf14694..a47dc5faf2e367e09c27daf648fe2e422a95c21b 100644 --- a/tests/wasm_tests/identity_tests.cpp +++ b/tests/wasm_tests/identity_tests.cpp @@ -614,7 +614,56 @@ BOOST_FIXTURE_TEST_CASE( owner_certification_becomes_trusted, identity_tester ) //but effectively bob's certification should became trusted BOOST_REQUIRE_EQUAL(N(alice), get_owner_for_identity(identity_val)); - } FC_LOG_AND_RETHROW() //owner_certification_becomes_trusted +} FC_LOG_AND_RETHROW() //owner_certification_becomes_trusted + +BOOST_FIXTURE_TEST_CASE( ownership_contradiction, identity_tester ) try { + BOOST_REQUIRE_EQUAL(success(), create_identity("alice", identity_val)); + + //alice claims identity + BOOST_REQUIRE_EQUAL(success(), certify("alice", identity_val, vector{ mutable_variant_object() + ("property", "owner") + ("type", "account") + ("data", to_uint8_vector(N(alice))) + ("memo", "claiming onwership") + ("confidence", 100) + })); + + // block producer certifies alice's ownership + BOOST_REQUIRE_EQUAL(success(), certify("inita", identity_val, vector{ mutable_variant_object() + ("property", "owner") + ("type", "account") + ("data", to_uint8_vector(N(alice))) + ("memo", "") + ("confidence", 100) + })); + BOOST_REQUIRE_EQUAL( true, get_certrow(identity_val, "owner", 1, "inita").is_object() ); + + //now alice is the official owner of the identity + BOOST_REQUIRE_EQUAL(N(alice), get_owner_for_identity(identity_val)); + + //bob claims identity + BOOST_REQUIRE_EQUAL(success(), certify("bob", identity_val, vector{ mutable_variant_object() + ("property", "owner") + ("type", "account") + ("data", to_uint8_vector(N(bob))) + ("memo", "claiming onwership") + ("confidence", 100) + })); + + //another block producer certifies bob's identity (to the identity already certified to alice) + BOOST_REQUIRE_EQUAL(success(), certify("initb", identity_val, vector{ mutable_variant_object() + ("property", "owner") + ("type", "account") + ("data", to_uint8_vector(N(bob))) + ("memo", "") + ("confidence", 100) + })); + BOOST_REQUIRE_EQUAL( true, get_certrow(identity_val, "owner", 1, "initb").is_object() ); + + //now neither alice or bob are official owners, because we have 2 trusted certifications in contradiction to each other + BOOST_REQUIRE_EQUAL(0, get_owner_for_identity(identity_val)); + +} FC_LOG_AND_RETHROW() //ownership_contradiction BOOST_AUTO_TEST_SUITE_END() #endif