forked from lthn/blockchain
new addresses formats + unit tests
This commit is contained in:
parent
c018cc89ae
commit
42a752d12b
5 changed files with 185 additions and 34 deletions
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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]);
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue