Make memo_test fail if serialization format changes

If this happens, the web guys need to be notified of the new format.
This commit is contained in:
Nathan Hourt 2015-07-06 17:38:04 -04:00
parent 7d6d7066c2
commit ab740d6aaa
3 changed files with 38 additions and 22 deletions

View file

@ -133,10 +133,8 @@ namespace graphene { namespace chain {
* @brief Claim a balance in a @ref balanc_object * @brief Claim a balance in a @ref balanc_object
* *
* This operation is used to claim the balance in a given @ref balance_object. If the balance object contains a * This operation is used to claim the balance in a given @ref balance_object. If the balance object contains a
* vesting balance, @ref total_claimed must be set to zero, and all available vested funds will be claimed. If the * vesting balance, @ref total_claimed must not exceed @ref balance_object::available at the time of evaluation. If
* object contains a non-vesting balance, @ref total_claimed must be the full balance of the object. * the object contains a non-vesting balance, @ref total_claimed must be the full balance of the object.
*
* This operation returns the total amount claimed.
*/ */
struct balance_claim_operation struct balance_claim_operation
{ {
@ -151,13 +149,12 @@ namespace graphene { namespace chain {
share_type calculate_fee(const fee_schedule_type& k)const { return 0; } share_type calculate_fee(const fee_schedule_type& k)const { return 0; }
void validate()const; void validate()const;
void get_balance_delta(balance_accumulator& acc, const operation_result& result)const { void get_balance_delta(balance_accumulator& acc, const operation_result& = asset())const {
acc.adjust(deposit_to_account, result.get<asset>()); acc.adjust(deposit_to_account, total_claimed);
acc.adjust(fee_payer(), -fee); acc.adjust(fee_payer(), -fee);
} }
}; };
/** /**
* @ingroup operations * @ingroup operations
*/ */
@ -455,17 +452,18 @@ namespace graphene { namespace chain {
* be unique with high probability as long as the generating host has a high-resolution clock OR a strong source * be unique with high probability as long as the generating host has a high-resolution clock OR a strong source
* of entropy for generating private keys. * of entropy for generating private keys.
*/ */
uint64_t nonce; uint64_t nonce;
/** /**
* This field contains the AES encrypted packed @ref memo_message * This field contains the AES encrypted packed @ref memo_message
*/ */
vector<char> message; vector<char> message;
void set_message( const fc::ecc::private_key& priv, /// @note custom_nonce is for debugging only; do not set to a nonzero value in production
const fc::ecc::public_key& pub, const string& msg ); void set_message(const fc::ecc::private_key& priv,
const fc::ecc::public_key& pub, const string& msg, uint64_t custom_nonce = 0);
std::string get_message( const fc::ecc::private_key& priv, std::string get_message(const fc::ecc::private_key& priv,
const fc::ecc::public_key& pub )const; const fc::ecc::public_key& pub)const;
}; };
/** /**

View file

@ -840,15 +840,19 @@ share_type vesting_balance_withdraw_operation::calculate_fee(const fee_schedule_
return k.vesting_balance_withdraw_fee; return k.vesting_balance_withdraw_fee;
} }
void memo_data::set_message( const fc::ecc::private_key& priv, void memo_data::set_message(const fc::ecc::private_key& priv, const fc::ecc::public_key& pub,
const fc::ecc::public_key& pub, const string& msg ) const string& msg, uint64_t custom_nonce)
{ {
if( from != public_key_type() ) if( from != public_key_type() )
{ {
uint64_t entropy = fc::sha224::hash(fc::ecc::private_key::generate())._hash[0]; if( custom_nonce == 0 )
entropy <<= 32; {
entropy &= 0xff00000000000000; uint64_t entropy = fc::sha224::hash(fc::ecc::private_key::generate())._hash[0];
nonce = (fc::time_point::now().time_since_epoch().count() & 0x00ffffffffffffff) | entropy; entropy <<= 32;
entropy &= 0xff00000000000000;
nonce = (fc::time_point::now().time_since_epoch().count() & 0x00ffffffffffffff) | entropy;
} else
nonce = custom_nonce;
auto secret = priv.get_shared_secret(pub); auto secret = priv.get_shared_secret(pub);
auto nonce_plus_secret = fc::sha512::hash(fc::to_string(nonce) + secret.str()); auto nonce_plus_secret = fc::sha512::hash(fc::to_string(nonce) + secret.str());
string text = memo_message(digest_type::hash(msg)._hash[0], msg).serialize(); string text = memo_message(digest_type::hash(msg)._hash[0], msg).serialize();
@ -856,13 +860,13 @@ void memo_data::set_message( const fc::ecc::private_key& priv,
} }
else else
{ {
auto text = memo_message( 0, msg ).serialize(); auto text = memo_message(0, msg).serialize();
message = vector<char>(text.begin(), text.end()); message = vector<char>(text.begin(), text.end());
} }
} }
string memo_data::get_message( const fc::ecc::private_key& priv, string memo_data::get_message(const fc::ecc::private_key& priv,
const fc::ecc::public_key& pub )const const fc::ecc::public_key& pub)const
{ {
if( from != public_key_type() ) if( from != public_key_type() )
{ {

View file

@ -25,6 +25,7 @@
#include <graphene/chain/asset_object.hpp> #include <graphene/chain/asset_object.hpp>
#include <graphene/chain/delegate_object.hpp> #include <graphene/chain/delegate_object.hpp>
#include <graphene/chain/witness_scheduler_rng.hpp> #include <graphene/chain/witness_scheduler_rng.hpp>
#include <graphene/chain/exceptions.hpp>
#include <graphene/db/simple_index.hpp> #include <graphene/db/simple_index.hpp>
@ -174,7 +175,15 @@ BOOST_AUTO_TEST_CASE( memo_test )
auto receiver = generate_private_key("2"); auto receiver = generate_private_key("2");
m.from = sender.get_public_key(); m.from = sender.get_public_key();
m.to = receiver.get_public_key(); m.to = receiver.get_public_key();
m.set_message(sender, receiver.get_public_key(), "Hello, world!"); m.set_message(sender, receiver.get_public_key(), "Hello, world!", 12345);
decltype(fc::digest(m)) hash("8de72a07d093a589f574460deb19023b4aff354b561eb34590d9f4629f51dbf3");
if( fc::digest(m) != hash )
{
// If this happens, notify the web guys that the memo serialization format changed.
edump((m)(fc::digest(m)));
BOOST_FAIL("Memo format has changed. Notify the web guys and update this test.");
}
BOOST_CHECK_EQUAL(m.get_message(receiver, sender.get_public_key()), "Hello, world!"); BOOST_CHECK_EQUAL(m.get_message(receiver, sender.get_public_key()), "Hello, world!");
} FC_LOG_AND_RETHROW() } } FC_LOG_AND_RETHROW() }
@ -319,4 +328,9 @@ BOOST_AUTO_TEST_CASE( data_fees )
BOOST_CHECK_EQUAL(fs.total_data_fee(keys, x), (fc::raw::pack_size(keys) + fc::raw::pack_size(x)) / 1024 * 10); BOOST_CHECK_EQUAL(fs.total_data_fee(keys, x), (fc::raw::pack_size(keys) + fc::raw::pack_size(x)) / 1024 * 10);
} }
BOOST_AUTO_TEST_CASE( exceptions )
{
BOOST_CHECK_THROW(FC_THROW_EXCEPTION(invalid_claim_amount, "Etc"), invalid_claim_amount);
}
BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE_END()