1
0
Fork 0
forked from lthn/blockchain

new addresses formats + unit tests

This commit is contained in:
sowle 2020-04-30 18:50:22 +03:00
parent c018cc89ae
commit 42a752d12b
No known key found for this signature in database
GPG key ID: C07A24B2D89D49FC
5 changed files with 185 additions and 34 deletions

View file

@ -86,36 +86,26 @@ namespace currency
#pragma pack(push, 1)
struct account_public_address
{
/*account_public_address()
{}
account_public_address(const account_public_address_old& rhs)
: version(ACCOUNT_PUBLIC_ADDRESS_SERIZALIZATION_VER)
, flags(0)
, spend_public_key(rhs.spend_public_key)
, view_public_key(rhs.view_public_key)
{}*/
uint8_t version;
uint8_t flags;
crypto::public_key spend_public_key;
crypto::public_key view_public_key;
//uint8_t version;
uint8_t flags;
DEFINE_SERIALIZATION_VERSION(ACCOUNT_PUBLIC_ADDRESS_SERIZALIZATION_VER)
BEGIN_SERIALIZE_OBJECT()
VERSION_ENTRY(version)
FIELD(flags)
FIELD(spend_public_key)
FIELD(view_public_key)
if (version > ACCOUNT_PUBLIC_ADDRESS_SERIZALIZATION_VER)
return true; // backward compartibility
//VERSION_ENTRY(version)
FIELD(flags)
//if (version > ACCOUNT_PUBLIC_ADDRESS_SERIZALIZATION_VER)
// return true; // backward compartibility
END_SERIALIZE()
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(version) // is it necessary?
KV_SERIALIZE(flags)
KV_SERIALIZE_VAL_POD_AS_BLOB_FORCE(spend_public_key)
KV_SERIALIZE_VAL_POD_AS_BLOB_FORCE(view_public_key)
//KV_SERIALIZE(version) // is it necessary?
KV_SERIALIZE(flags)
END_KV_SERIALIZE_MAP()
static account_public_address from_old(const account_public_address_old& rhs)

View file

@ -29,7 +29,7 @@ namespace boost
template <class Archive>
inline void serialize(Archive &a, currency::account_public_address &x, const boost::serialization::version_type ver)
{
a & x.version;
//a & x.version;
a & x.flags;
a & x.spend_public_key;
a & x.view_public_key;

View file

@ -20,8 +20,11 @@
#define CURRENCY_MAX_BLOCK_NUMBER 500000000
#define CURRENCY_MAX_BLOCK_SIZE 500000000 // block header blob limit, never used!
#define CURRENCY_TX_MAX_ALLOWED_OUTS 2000
#define CURRENCY_PUBLIC_ADDRESS_BASE58_PREFIX 197 // addresses start with 'Z'
#define CURRENCY_PUBLIC_ADDRESS_BASE58_PREFIX 0xc5 // addresses start with 'Zx'
#define CURRENCY_PUBLIC_INTEG_ADDRESS_BASE58_PREFIX 0x3678 // integrated addresses start with 'iZ'
#define CURRENCY_PUBLIC_INTEG_ADDRESS_V2_BASE58_PREFIX 0x36f8 // integrated addresses start with 'iZ' (new format)
#define CURRENCY_PUBLIC_AUDITABLE_ADDRESS_BASE58_PREFIX 0x98c8 // auditable addresses start with 'aZx'
#define CURRENCY_PUBLIC_AUDITABLE_INTEG_ADDRESS_BASE58_PREFIX 0x8a49 // auditable integrated addresses start with 'aiZX'
#define CURRENCY_MINED_MONEY_UNLOCK_WINDOW 10
#define CURRENT_TRANSACTION_VERSION 1
#define CURRENT_BLOCK_MAJOR_VERSION 1

View file

@ -2511,12 +2511,24 @@ namespace currency
//-----------------------------------------------------------------------
std::string get_account_address_as_str(const account_public_address& addr)
{
return tools::base58::encode_addr(CURRENCY_PUBLIC_ADDRESS_BASE58_PREFIX, t_serializable_object_to_blob(addr));
if (addr.flags == 0)
return tools::base58::encode_addr(CURRENCY_PUBLIC_ADDRESS_BASE58_PREFIX, t_serializable_object_to_blob(addr.to_old())); // classic Zano address
if (addr.flags & ACCOUNT_PUBLIC_ADDRESS_FLAG_AUDITABLE)
return tools::base58::encode_addr(CURRENCY_PUBLIC_AUDITABLE_ADDRESS_BASE58_PREFIX, t_serializable_object_to_blob(addr)); // new format Zano address (auditable)
return tools::base58::encode_addr(CURRENCY_PUBLIC_ADDRESS_BASE58_PREFIX, t_serializable_object_to_blob(addr)); // new format Zano address (normal)
}
//-----------------------------------------------------------------------
std::string get_account_address_and_payment_id_as_str(const account_public_address& addr, const payment_id_t& payment_id)
{
return tools::base58::encode_addr(CURRENCY_PUBLIC_INTEG_ADDRESS_BASE58_PREFIX, t_serializable_object_to_blob(addr) + payment_id);
if (addr.flags == 0)
return tools::base58::encode_addr(CURRENCY_PUBLIC_INTEG_ADDRESS_BASE58_PREFIX, t_serializable_object_to_blob(addr.to_old()) + payment_id); // classic integrated Zano address
if (addr.flags & ACCOUNT_PUBLIC_ADDRESS_FLAG_AUDITABLE)
return tools::base58::encode_addr(CURRENCY_PUBLIC_AUDITABLE_INTEG_ADDRESS_BASE58_PREFIX, t_serializable_object_to_blob(addr) + payment_id); // new format integrated Zano address (auditable)
return tools::base58::encode_addr(CURRENCY_PUBLIC_INTEG_ADDRESS_V2_BASE58_PREFIX, t_serializable_object_to_blob(addr) + payment_id); // new format integrated Zano address (normal)
}
//-----------------------------------------------------------------------
bool get_account_address_from_str(account_public_address& addr, const std::string& str)
@ -2527,7 +2539,7 @@ namespace currency
//-----------------------------------------------------------------------
bool get_account_address_and_payment_id_from_str(account_public_address& addr, payment_id_t& payment_id, const std::string& str)
{
static const size_t addr_blob_size = sizeof(account_public_address);
payment_id.clear();
blobdata blob;
uint64_t prefix;
if (!tools::base58::decode_addr(str, prefix, blob))
@ -2536,42 +2548,88 @@ namespace currency
return false;
}
if (blob.size() < addr_blob_size)
if (blob.size() < sizeof(account_public_address_old))
{
LOG_PRINT_L1("Address " << str << " has invalid format: blob size is " << blob.size() << " which is less, than expected " << addr_blob_size);
LOG_PRINT_L1("Address " << str << " has invalid format: blob size is " << blob.size() << " which is less, than expected " << sizeof(account_public_address_old));
return false;
}
if (blob.size() > addr_blob_size + BC_PAYMENT_ID_SERVICE_SIZE_MAX)
if (blob.size() > sizeof(account_public_address) + BC_PAYMENT_ID_SERVICE_SIZE_MAX)
{
LOG_PRINT_L1("Address " << str << " has invalid format: blob size is " << blob.size() << " which is more, than allowed " << addr_blob_size + BC_PAYMENT_ID_SERVICE_SIZE_MAX);
LOG_PRINT_L1("Address " << str << " has invalid format: blob size is " << blob.size() << " which is more, than allowed " << sizeof(account_public_address) + BC_PAYMENT_ID_SERVICE_SIZE_MAX);
return false;
}
bool parse_as_old_format = false;
if (prefix == CURRENCY_PUBLIC_ADDRESS_BASE58_PREFIX)
{
// nothing
// normal address
if (blob.size() == sizeof(account_public_address_old))
{
parse_as_old_format = true;
}
else if (blob.size() == sizeof(account_public_address))
{
parse_as_old_format = false;
}
else
{
LOG_PRINT_L1("Account public address cannot be parsed from \"" << str << "\", incorrect size");
return false;
}
}
else if (prefix == CURRENCY_PUBLIC_AUDITABLE_ADDRESS_BASE58_PREFIX)
{
// auditable, parse as new format
parse_as_old_format = false;
}
else if (prefix == CURRENCY_PUBLIC_INTEG_ADDRESS_BASE58_PREFIX)
{
payment_id = blob.substr(addr_blob_size);
blob = blob.substr(0, addr_blob_size);
payment_id = blob.substr(sizeof(account_public_address_old));
blob = blob.substr(0, sizeof(account_public_address_old));
parse_as_old_format = true;
}
else if (prefix == CURRENCY_PUBLIC_AUDITABLE_INTEG_ADDRESS_BASE58_PREFIX || prefix == CURRENCY_PUBLIC_INTEG_ADDRESS_V2_BASE58_PREFIX)
{
payment_id = blob.substr(sizeof(account_public_address));
blob = blob.substr(0, sizeof(account_public_address));
parse_as_old_format = false;
}
else
{
LOG_PRINT_L1("Address " << str << " has wrong prefix " << prefix << ", expected " << CURRENCY_PUBLIC_ADDRESS_BASE58_PREFIX << " or " << CURRENCY_PUBLIC_INTEG_ADDRESS_BASE58_PREFIX);
LOG_PRINT_L1("Address " << str << " has wrong prefix " << prefix);
return false;
}
if (!::serialization::parse_binary(blob, addr))
if (parse_as_old_format)
{
LOG_PRINT_L1("Account public address keys can't be parsed for address \"" << str << "\"");
account_public_address_old addr_old = AUTO_VAL_INIT(addr_old);
if (!::serialization::parse_binary(blob, addr_old))
{
LOG_PRINT_L1("Account public address (old) cannot be parsed from \"" << str << "\"");
return false;
}
addr = account_public_address::from_old(addr_old);
}
else
{
if (!::serialization::parse_binary(blob, addr))
{
LOG_PRINT_L1("Account public address cannot be parsed from \"" << str << "\"");
return false;
}
}
if (payment_id.size() > BC_PAYMENT_ID_SERVICE_SIZE_MAX)
{
LOG_PRINT_L1("Failed to parse address from \"" << str << "\": payment id size exceeded: " << payment_id.size());
return false;
}
if (!crypto::check_key(addr.spend_public_key) || !crypto::check_key(addr.view_public_key))
{
LOG_PRINT_L1("Failed to validate address keys for address \"" << str << "\"");
LOG_PRINT_L1("Failed to validate address keys for public address \"" << str << "\"");
return false;
}

View file

@ -551,3 +551,103 @@ TEST(integ_address, payment_id_sizes)
ASSERT_NE(addr2, addr);
ASSERT_NE(integrated_payment_id, payment_id);
}
struct addr_entry_t
{
std::string address;
std::string view_pub_key;
std::string spend_pub_key;
std::string payment_id_hex;
uint8_t flags;
};
addr_entry_t addr_entries[] =
{
{
// classic normal address
"ZxD5aoLDPTdcaRx4uCpyW4XiLfEXejepAVz8cSY2fwHNEiJNu6NmpBBDLGTJzCsUvn3acCVDVDPMV8yQXdPooAp338Se7AxeH", // address
"a3f208c8f9ba49bab28eed62b35b0f6be0a297bcd85c2faa1eb1820527bcf7e3", // view_pub_key
"9f5e1fa93630d4b281b18bb67a3db79e9622fc703cc3ad4a453a82e0a36d51fa", // spend_pub_key
"", // payment_id_hex
0 // flags
},
{
// classic integrated address
"iZ2Zi6RmTWwcaRx4uCpyW4XiLfEXejepAVz8cSY2fwHNEiJNu6NmpBBDLGTJzCsUvn3acCVDVDPMV8yQXdPooAp3iTqEsjvJoco1aLSZXS6T", // address
"a3f208c8f9ba49bab28eed62b35b0f6be0a297bcd85c2faa1eb1820527bcf7e3", // view_pub_key
"9f5e1fa93630d4b281b18bb67a3db79e9622fc703cc3ad4a453a82e0a36d51fa", // spend_pub_key
"87440d0b9acc42f1", // payment_id_hex
0 // flags
},
{
// new format normal address with custom flags
"ZxD5aoLDPTdcaRx4uCpyW4XiLfEXejepAVz8cSY2fwHNEiJNu6NmpBBDLGTJzCsUvn3acCVDVDPMV8yQXdPooAp3APrDvRoL5C", // address
"a3f208c8f9ba49bab28eed62b35b0f6be0a297bcd85c2faa1eb1820527bcf7e3", // view_pub_key
"9f5e1fa93630d4b281b18bb67a3db79e9622fc703cc3ad4a453a82e0a36d51fa", // spend_pub_key
"", // payment_id_hex
0xfe // flags
},
{
// new format integrated address with custom flags
"iZ4mBxubNfqcaRx4uCpyW4XiLfEXejepAVz8cSY2fwHNEiJNu6NmpBBDLGTJzCsUvn3acCVDVDPMV8yQXdPooAp3iTrG7nU5rRCWmcozLaMoY95sAbo6", // address
"a3f208c8f9ba49bab28eed62b35b0f6be0a297bcd85c2faa1eb1820527bcf7e3", // view_pub_key
"9f5e1fa93630d4b281b18bb67a3db79e9622fc703cc3ad4a453a82e0a36d51fa", // spend_pub_key
"3ba0527bcfb1fa93630d28eed6", // payment_id
0xfe // flags
},
{
// normal auditable address
"aZxb9Et6FhP9AinRwcPqSqBKjckre7PgoZjK3q5YG2fUKHYWFZMWjB6YAEAdw4yDDUGEQ7CGEgbqhGRKeadGV1jLYcEJMEmqQFn", // address
"a3f208c8f9ba49bab28eed62b35b0f6be0a297bcd85c2faa1eb1820527bcf7e3", // view_pub_key
"9f5e1fa93630d4b281b18bb67a3db79e9622fc703cc3ad4a453a82e0a36d51fa", // spend_pub_key
"", // payment_id
ACCOUNT_PUBLIC_ADDRESS_FLAG_AUDITABLE // flags
},
{
// auditable integrated address
"aiZXDondHWu9AinRwcPqSqBKjckre7PgoZjK3q5YG2fUKHYWFZMWjB6YAEAdw4yDDUGEQ7CGEgbqhGRKeadGV1jLYcEJM9xJH8EbjuRiMJgFmPRATsEV9", // address
"a3f208c8f9ba49bab28eed62b35b0f6be0a297bcd85c2faa1eb1820527bcf7e3", // view_pub_key
"9f5e1fa93630d4b281b18bb67a3db79e9622fc703cc3ad4a453a82e0a36d51fa", // spend_pub_key
"3ba0527bcfb1fa93630d28eed6", // payment_id
ACCOUNT_PUBLIC_ADDRESS_FLAG_AUDITABLE // flags
}
};
void check_add_entry(const addr_entry_t& ae)
{
std::string payment_id, payment_id_hex;
currency::account_public_address addr = AUTO_VAL_INIT(addr);
ASSERT_TRUE(currency::get_account_address_and_payment_id_from_str(addr, payment_id, ae.address));
payment_id_hex = epee::string_tools::buff_to_hex_nodelimer(payment_id);
ASSERT_EQ(ae.flags, addr.flags);
ASSERT_EQ(ae.payment_id_hex, payment_id_hex);
ASSERT_EQ(ae.view_pub_key, epee::string_tools::pod_to_hex(addr.view_public_key));
ASSERT_EQ(ae.spend_pub_key, epee::string_tools::pod_to_hex(addr.spend_public_key));
}
TEST(auditable_addresses, basic)
{
/*
currency::account_keys keys = AUTO_VAL_INIT(keys);
epee::string_tools::parse_tpod_from_hex_string("248b019d145d485576ecb0367d92b5a12e8aa15084b59ef15014a7a22d1f3b0c", keys.spend_secret_key);
dependent_key(keys.spend_secret_key, keys.view_secret_key);
crypto::secret_key_to_public_key(keys.view_secret_key, keys.account_address.view_public_key);
crypto::secret_key_to_public_key(keys.spend_secret_key, keys.account_address.spend_public_key);
keys.account_address.flags = 0xfe;
std::string payment_id;
epee::string_tools::parse_hexstr_to_binbuff(std::string("3ba0527bcfb1fa93630d28eed6"), payment_id);
std::cout << currency::get_account_address_as_str(keys.account_address) << " " << epee::string_tools::pod_to_hex(keys.account_address.view_public_key) << " " << epee::string_tools::pod_to_hex(keys.account_address.spend_public_key) << ENDL;
std::cout << currency::get_account_address_and_payment_id_as_str(keys.account_address, payment_id) << " " << epee::string_tools::pod_to_hex(keys.account_address.view_public_key) << " " << epee::string_tools::pod_to_hex(keys.account_address.spend_public_key) << ENDL;
*/
for (size_t i = 0; i < sizeof addr_entries / sizeof addr_entries[0]; ++i)
check_add_entry(addr_entries[i]);
}