Skip to content
This repository has been archived by the owner on Dec 29, 2018. It is now read-only.

Commit

Permalink
Merge pull request #122 from pmconrad/release_candidate
Browse files Browse the repository at this point in the history
Bugfix release with soft fork
  • Loading branch information
pmconrad committed Jul 19, 2018
2 parents d510281 + 613de29 commit 2ba60b7
Show file tree
Hide file tree
Showing 6 changed files with 145 additions and 50 deletions.
6 changes: 5 additions & 1 deletion libraries/chain/base_evaluator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,9 @@ void withdraw_vesting_evaluator::do_apply( const withdraw_vesting_operation& o )
{
const auto& account = db().get_account( o.account );

if( db().head_block_time() > fc::time_point::now() - fc::seconds(15) ) // SOFT FORK
FC_ASSERT( o.vesting_shares.amount >= 0, "Cannot withdraw a negative amount of VESTS!" );

FC_ASSERT( account.vesting_shares >= asset( 0, VESTS_SYMBOL ) );
FC_ASSERT( account.vesting_shares >= o.vesting_shares );

Expand All @@ -324,7 +327,8 @@ void withdraw_vesting_evaluator::do_apply( const withdraw_vesting_operation& o )



if( o.vesting_shares.amount == 0 ) {
if( o.vesting_shares.amount <= 0 ) {
if( o.vesting_shares.amount == 0 ) // SOFT FORK
FC_ASSERT( account.vesting_withdraw_rate.amount != 0, "this operation would not change the vesting withdraw rate" );

db().modify( account, [&]( account_object& a ) {
Expand Down
52 changes: 26 additions & 26 deletions libraries/chain/database.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -778,12 +778,34 @@ signed_block database::_generate_block(
if( !(skip & skip_witness_signature) )
FC_ASSERT( witness_obj.signing_key == block_signing_private_key.get_public_key() );

static const size_t max_block_header_size = fc::raw::pack_size( signed_block_header() ) + 4;
auto maximum_block_size = get_dynamic_global_properties().maximum_block_size; //MUSE_MAX_BLOCK_SIZE;
size_t total_block_size = max_block_header_size;

signed_block pending_block;

pending_block.previous = head_block_id();
pending_block.timestamp = when;
pending_block.witness = witness_owner;
const auto& witness = get_witness( witness_owner );

if( witness.running_version != MUSE_BLOCKCHAIN_VERSION )
pending_block.extensions.insert( block_header_extensions( MUSE_BLOCKCHAIN_VERSION ) );

const auto& hfp = hardfork_property_id_type()( *this );

if( hfp.current_hardfork_version < MUSE_BLOCKCHAIN_HARDFORK_VERSION // Binary is newer hardfork than has been applied
&& ( witness.hardfork_version_vote != _hardfork_versions[ hfp.last_hardfork + 1 ] || witness.hardfork_time_vote != _hardfork_times[ hfp.last_hardfork + 1 ] ) ) // Witness vote does not match binary configuration
{
// Make vote match binary configuration
pending_block.extensions.insert( block_header_extensions( hardfork_version_vote( _hardfork_versions[ hfp.last_hardfork + 1 ], _hardfork_times[ hfp.last_hardfork + 1 ] ) ) );
}
else if( hfp.current_hardfork_version == MUSE_BLOCKCHAIN_HARDFORK_VERSION // Binary does not know of a new hardfork
&& witness.hardfork_version_vote > MUSE_BLOCKCHAIN_HARDFORK_VERSION ) // Voting for hardfork in the future, that we do not know of...
{
// Make vote match binary configuration. This is vote to not apply the new hardfork.
pending_block.extensions.insert( block_header_extensions( hardfork_version_vote( _hardfork_versions[ hfp.last_hardfork ], _hardfork_times[ hfp.last_hardfork ] ) ) );
}
// The 4 is for the max size of the transaction vector length
size_t total_block_size = fc::raw::pack_size( pending_block ) + 4;
auto maximum_block_size = get_dynamic_global_properties().maximum_block_size;

//
// The following code throws away existing pending_tx_session and
// rebuilds it by re-applying pending transactions.
Expand Down Expand Up @@ -846,29 +868,7 @@ signed_block database::_generate_block(
// However, the push_block() call below will re-create the
// _pending_tx_session.

pending_block.previous = head_block_id();
pending_block.timestamp = when;
pending_block.transaction_merkle_root = pending_block.calculate_merkle_root();
pending_block.witness = witness_owner;
const auto& witness = get_witness( witness_owner );

if( witness.running_version != MUSE_BLOCKCHAIN_VERSION )
pending_block.extensions.insert( block_header_extensions( MUSE_BLOCKCHAIN_VERSION ) );

const auto& hfp = hardfork_property_id_type()( *this );

if( hfp.current_hardfork_version < MUSE_BLOCKCHAIN_HARDFORK_VERSION // Binary is newer hardfork than has been applied
&& ( witness.hardfork_version_vote != _hardfork_versions[ hfp.last_hardfork + 1 ] || witness.hardfork_time_vote != _hardfork_times[ hfp.last_hardfork + 1 ] ) ) // Witness vote does not match binary configuration
{
// Make vote match binary configuration
pending_block.extensions.insert( block_header_extensions( hardfork_version_vote( _hardfork_versions[ hfp.last_hardfork + 1 ], _hardfork_times[ hfp.last_hardfork + 1 ] ) ) );
}
else if( hfp.current_hardfork_version == MUSE_BLOCKCHAIN_HARDFORK_VERSION // Binary does not know of a new hardfork
&& witness.hardfork_version_vote > MUSE_BLOCKCHAIN_HARDFORK_VERSION ) // Voting for hardfork in the future, that we do not know of...
{
// Make vote match binary configuration. This is vote to not apply the new hardfork.
pending_block.extensions.insert( block_header_extensions( hardfork_version_vote( _hardfork_versions[ hfp.last_hardfork ], _hardfork_times[ hfp.last_hardfork ] ) ) );
}

if( !(skip & skip_witness_signature) )
pending_block.sign( block_signing_private_key );
Expand Down
2 changes: 1 addition & 1 deletion libraries/chain/include/muse/chain/config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
*/
#pragma once

#define MUSE_BLOCKCHAIN_VERSION ( version(0, 3, 1) )
#define MUSE_BLOCKCHAIN_VERSION ( version(0, 3, 2) )
#define MUSE_BLOCKCHAIN_HARDFORK_VERSION ( hardfork_version( MUSE_BLOCKCHAIN_VERSION ) )

#ifdef IS_TEST_NET // This is the muse test net mode. Some feature may behave differently
Expand Down
1 change: 1 addition & 0 deletions libraries/chain/protocol/base_operations.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ namespace muse { namespace chain {
{
FC_ASSERT( is_valid_account_name( account ), "Account name invalid" );
FC_ASSERT( is_asset_type( vesting_shares, VESTS_SYMBOL), "Amount must be VESTS" );
//FC_ASSERT( vesting_shares.amount >= 0, "Cannot withdraw a negative amount of VESTS!" );
}

void set_withdraw_vesting_route_operation::validate() const
Expand Down
69 changes: 69 additions & 0 deletions tests/tests/block_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1025,4 +1025,73 @@ BOOST_FIXTURE_TEST_CASE( clear_witness_key, clean_database_fixture )

} FC_LOG_AND_RETHROW() }

BOOST_FIXTURE_TEST_CASE( generate_block_size, clean_database_fixture )
{
try
{
generate_block();

db.modify( db.get_dynamic_global_properties(), []( dynamic_global_property_object& gpo )
{
gpo.maximum_block_size = MUSE_MIN_BLOCK_SIZE_LIMIT;
});

signed_transaction tx;
tx.set_expiration( db.head_block_time() + MUSE_MAX_TIME_UNTIL_EXPIRATION );

transfer_operation op;
op.from = MUSE_INIT_MINER_NAME;
op.to = MUSE_TEMP_ACCOUNT;
op.amount = asset( 1000, MUSE_SYMBOL );

// tx without ops is 78 bytes (77 + 1 for length of ops vector))
// op is 26 bytes (25 for op + 1 byte static variant tag)
// total is 65182
std::vector<char> raw_op = fc::raw::pack_to_vector( op, 255 );
BOOST_CHECK_EQUAL( 25, raw_op.size() );
BOOST_CHECK_EQUAL( raw_op.size(), fc::raw::pack_size( op ) );

for( size_t i = 0; i < 2507; i++ )
{
tx.operations.push_back( op );
}

tx.sign( init_account_priv_key, db.get_chain_id() );
db.push_transaction( tx, 0 );

std::vector<char> raw_tx = fc::raw::pack_to_vector( tx, 255 );
BOOST_CHECK_EQUAL( 65182+77+2, raw_tx.size() ); // 2 bytes for encoding # of ops
BOOST_CHECK_EQUAL( raw_tx.size(), fc::raw::pack_size( tx ) );

// Original generation logic only allowed 115 bytes for the header
BOOST_CHECK_EQUAL( 115, fc::raw::pack_size( signed_block_header() ) + 4 );
// We are targetting a size (minus header) of 65420 which creates a block of "size" 65535
// This block will actually be larger because the header estimates is too small

// Second transaction
// We need a 80 (65420 - (65182+77+2) - (77+1) - 1) byte op. We need a 55 character memo (1 byte for length); 54 = 80 - 25 (old op) - 1 (tag)
op.memo = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ123";
raw_op = fc::raw::pack_to_vector( op, 255 );
BOOST_CHECK_EQUAL( 80, raw_op.size() );
BOOST_CHECK_EQUAL( raw_op.size(), fc::raw::pack_size( op ) );

tx.clear();
tx.operations.push_back( op );
sign( tx, init_account_priv_key );
db.push_transaction( tx, 0 );

raw_tx = fc::raw::pack_to_vector( tx, 255 );
BOOST_CHECK_EQUAL( 78+80+1, raw_tx.size() );
BOOST_CHECK_EQUAL( raw_tx.size(), fc::raw::pack_size( tx ) );

generate_block();
auto head_block = db.fetch_block_by_number( db.head_block_num() );
BOOST_CHECK_GE( 65535, fc::raw::pack_size( head_block ) );

// The last transfer should have been delayed due to size
BOOST_CHECK_EQUAL( 1, head_block->transactions.size() );
}
FC_LOG_AND_RETHROW()
}

BOOST_AUTO_TEST_SUITE_END()
65 changes: 43 additions & 22 deletions tests/tests/operation_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1265,57 +1265,78 @@ BOOST_AUTO_TEST_CASE( withdraw_vesting_apply )
fund( "alice", 10000000 );
vest( "alice", 10000000 );

BOOST_TEST_MESSAGE( "--- Test withdraw of existing VESTS" );
BOOST_TEST_MESSAGE( "--- Test failure withdrawing negative VESTS" );

withdraw_vesting_operation op;
op.account = "alice";
op.vesting_shares = asset( alice.vesting_shares.amount / 2, VESTS_SYMBOL );
op.vesting_shares = asset( -1, VESTS_SYMBOL );

auto old_vesting_shares = alice.vesting_shares;
generate_blocks( fc::time_point::now() - fc::seconds(30) );

signed_transaction tx;
tx.operations.push_back( op );
tx.set_expiration( db.head_block_time() + MUSE_MAX_TIME_UNTIL_EXPIRATION );
tx.sign( alice_private_key, db.get_chain_id() );
db.push_transaction( tx, 0 );
// works, but sets withdraw_rate to 0
BOOST_CHECK_EQUAL( 0, db.get_account("alice").vesting_withdraw_rate.amount.value );

generate_blocks( fc::time_point::now() - fc::seconds(10) );

tx.set_expiration( db.head_block_time() + MUSE_MAX_TIME_UNTIL_EXPIRATION );
tx.signatures.clear();
tx.sign( alice_private_key, db.get_chain_id() );
// fails
MUSE_REQUIRE_THROW( db.push_transaction( tx, 0 ), fc::assert_exception );


BOOST_TEST_MESSAGE( "--- Test withdraw of existing VESTS" );
op.vesting_shares = asset( db.get_account("alice").vesting_shares.amount / 2, VESTS_SYMBOL );

auto old_vesting_shares = db.get_account("alice").vesting_shares;

tx.clear();
tx.operations.push_back( op );
tx.sign( alice_private_key, db.get_chain_id() );
db.push_transaction( tx, 0 );

BOOST_REQUIRE_EQUAL( alice.vesting_shares.amount.value, old_vesting_shares.amount.value );
BOOST_REQUIRE_EQUAL( alice.vesting_withdraw_rate.amount.value, ( old_vesting_shares.amount / 2 / MUSE_VESTING_WITHDRAW_INTERVALS ).value );
BOOST_REQUIRE_EQUAL( alice.to_withdraw.value, op.vesting_shares.amount.value );
BOOST_REQUIRE( alice.next_vesting_withdrawal == db.head_block_time() + MUSE_VESTING_WITHDRAW_INTERVAL_SECONDS );
BOOST_REQUIRE_EQUAL( db.get_account("alice").vesting_shares.amount.value, old_vesting_shares.amount.value );
BOOST_REQUIRE_EQUAL( db.get_account("alice").vesting_withdraw_rate.amount.value, ( old_vesting_shares.amount / 2 / MUSE_VESTING_WITHDRAW_INTERVALS ).value );
BOOST_REQUIRE_EQUAL( db.get_account("alice").to_withdraw.value, op.vesting_shares.amount.value );
BOOST_REQUIRE( db.get_account("alice").next_vesting_withdrawal == db.head_block_time() + MUSE_VESTING_WITHDRAW_INTERVAL_SECONDS );
validate_database();

BOOST_TEST_MESSAGE( "--- Test changing vesting withdrawal" );
tx.operations.clear();
tx.signatures.clear();

op.vesting_shares = asset( alice.vesting_shares.amount / 3, VESTS_SYMBOL );
op.vesting_shares = asset( db.get_account("alice").vesting_shares.amount / 3, VESTS_SYMBOL );
tx.operations.push_back( op );
tx.set_expiration( db.head_block_time() + MUSE_MAX_TIME_UNTIL_EXPIRATION );
tx.sign( alice_private_key, db.get_chain_id() );
db.push_transaction( tx, 0 );

BOOST_REQUIRE_EQUAL( alice.vesting_shares.amount.value, old_vesting_shares.amount.value );
BOOST_REQUIRE_EQUAL( alice.vesting_withdraw_rate.amount.value, ( old_vesting_shares.amount / 3 / MUSE_VESTING_WITHDRAW_INTERVALS ).value );
BOOST_REQUIRE_EQUAL( alice.to_withdraw.value, op.vesting_shares.amount.value );
BOOST_REQUIRE( alice.next_vesting_withdrawal == db.head_block_time() + MUSE_VESTING_WITHDRAW_INTERVAL_SECONDS );
BOOST_REQUIRE_EQUAL( db.get_account("alice").vesting_shares.amount.value, old_vesting_shares.amount.value );
BOOST_REQUIRE_EQUAL( db.get_account("alice").vesting_withdraw_rate.amount.value, ( old_vesting_shares.amount / 3 / MUSE_VESTING_WITHDRAW_INTERVALS ).value );
BOOST_REQUIRE_EQUAL( db.get_account("alice").to_withdraw.value, op.vesting_shares.amount.value );
BOOST_REQUIRE( db.get_account("alice").next_vesting_withdrawal == db.head_block_time() + MUSE_VESTING_WITHDRAW_INTERVAL_SECONDS );
validate_database();

BOOST_TEST_MESSAGE( "--- Test withdrawing more VESTS than available" );
auto old_withdraw_amount = alice.to_withdraw;
auto old_withdraw_amount = db.get_account("alice").to_withdraw;
tx.operations.clear();
tx.signatures.clear();

op.vesting_shares = asset( alice.vesting_shares.amount * 2, VESTS_SYMBOL );
op.vesting_shares = asset( db.get_account("alice").vesting_shares.amount * 2, VESTS_SYMBOL );
tx.operations.push_back( op );
tx.set_expiration( db.head_block_time() + MUSE_MAX_TIME_UNTIL_EXPIRATION );
tx.sign( alice_private_key, db.get_chain_id() );
MUSE_REQUIRE_THROW( db.push_transaction( tx, 0 ), fc::assert_exception );

BOOST_REQUIRE_EQUAL( alice.to_withdraw.value, old_withdraw_amount.value );
BOOST_REQUIRE_EQUAL( alice.vesting_shares.amount.value, old_vesting_shares.amount.value );
BOOST_REQUIRE_EQUAL( alice.vesting_withdraw_rate.amount.value, ( old_vesting_shares.amount / 3 / MUSE_VESTING_WITHDRAW_INTERVALS ).value );
BOOST_REQUIRE( alice.next_vesting_withdrawal == db.head_block_time() + MUSE_VESTING_WITHDRAW_INTERVAL_SECONDS );
BOOST_REQUIRE_EQUAL( db.get_account("alice").to_withdraw.value, old_withdraw_amount.value );
BOOST_REQUIRE_EQUAL( db.get_account("alice").vesting_shares.amount.value, old_vesting_shares.amount.value );
BOOST_REQUIRE_EQUAL( db.get_account("alice").vesting_withdraw_rate.amount.value, ( old_vesting_shares.amount / 3 / MUSE_VESTING_WITHDRAW_INTERVALS ).value );
BOOST_REQUIRE( db.get_account("alice").next_vesting_withdrawal == db.head_block_time() + MUSE_VESTING_WITHDRAW_INTERVAL_SECONDS );
validate_database();

BOOST_TEST_MESSAGE( "--- Test withdrawing 0 to resent vesting withdraw" );
Expand All @@ -1328,10 +1349,10 @@ BOOST_AUTO_TEST_CASE( withdraw_vesting_apply )
tx.sign( alice_private_key, db.get_chain_id() );
db.push_transaction( tx, 0 );

BOOST_REQUIRE_EQUAL( alice.vesting_shares.amount.value, old_vesting_shares.amount.value );
BOOST_REQUIRE_EQUAL( alice.vesting_withdraw_rate.amount.value, 0 );
BOOST_REQUIRE_EQUAL( alice.to_withdraw.value, 0 );
BOOST_REQUIRE( alice.next_vesting_withdrawal == fc::time_point_sec::maximum() );
BOOST_REQUIRE_EQUAL( db.get_account("alice").vesting_shares.amount.value, old_vesting_shares.amount.value );
BOOST_REQUIRE_EQUAL( db.get_account("alice").vesting_withdraw_rate.amount.value, 0 );
BOOST_REQUIRE_EQUAL( db.get_account("alice").to_withdraw.value, 0 );
BOOST_REQUIRE( db.get_account("alice").next_vesting_withdrawal == fc::time_point_sec::maximum() );
}
FC_LOG_AND_RETHROW()
}
Expand Down

0 comments on commit 2ba60b7

Please sign in to comment.