diff --git a/README.md b/README.md index b246ac24..7e06a971 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ Starting Graphene For Ubuntu 14.04 LTS users, see this link first: https://github.com/cryptonomex/graphene/wiki/build-ubuntu - + and then proceed with: git clone https://github.com/cryptonomex/graphene.git @@ -18,7 +18,9 @@ and then proceed with: make ./programs/witness_node/witness_node -This will launch the witness node. If you would like to launch the command-line wallet, you must first specify a port for communication with the witness node. To do this, add text to `witness_node_data_dir/config.ini` as follows, then restart the node: +This will launch the witness node. If you would like to launch the command-line wallet, you must first specify a port +for communication with the witness node. To do this, add text to `witness_node_data_dir/config.ini` as follows, then +restart the node: rpc-endpoint = 127.0.0.1:8090 @@ -37,7 +39,8 @@ To import your initial balance: If you send private keys over this connection, `rpc-endpoint` should be bound to localhost for security. -A list of CLI wallet commands is available [here](https://bitshares.github.io/doxygen/classgraphene_1_1wallet_1_1wallet__api.html). +A list of CLI wallet commands is available +[here](https://github.com/cryptonomex/graphene/blob/master/libraries/wallet/include/graphene/wallet/wallet.hpp). Code coverage testing --------------------- @@ -79,7 +82,9 @@ Witness node The role of the witness node is to broadcast transactions, download blocks, and optionally sign them. -./witness_node --rpc-endpoint "127.0.0.1:8090" --enable-stale-production -w \""1.6.0"\" \""1.6.1"\" \""1.6.2"\" \""1.6.3"\" \""1.6.4"\" +``` +./witness_node --rpc-endpoint "127.0.0.1:8090" --enable-stale-production -w \""1.6.0"\" \""1.6.1"\" \""1.6.2"\" \""1.6.3"\" \""1.6.4"\" +``` Running specific tests ---------------------- @@ -107,7 +112,7 @@ Here is an example using `wscat` package from `npm` for websockets: We can do the same thing using an HTTP client such as `curl` for API's which do not require login or other session state: $ curl --data '{"jsonrpc": "2.0", "method": "call", "params": [0, "get_accounts", [["1.2.0"]]], "id": 1}' http://127.0.0.1:8090/rpc - {"id":1,"result":[{"id":"1.2.0","annotations":[],"registrar":"1.2.0","referrer":"1.2.0","referrer_percent":0,"name":"genesis","owner":{"weight_threshold":1,"key_auths":[["PUBLIC_KEY",1]]},"active":{"weight_threshold":1,"key_auths":[["PUBLIC_KEY",1]]},"memo_key":"PUBLIC_KEY","voting_account":"1.2.0","num_witness":0,"num_committee":0,"votes":[],"statistics":"2.7.0","whitelisting_accounts":[],"blacklisting_accounts":[]}]} + {"id":1,"result":[{"id":"1.2.0","annotations":[],"registrar":"1.2.0","referrer":"1.2.0","referrer_percent":0,"name":"genesis","owner":{"weight_threshold":1,"key_auths":[["PUBLIC_KEY",1]]},"active":{"weight_threshold":1,"key_auths":[["PUBLIC_KEY",1]]},"memo_key":"PUBLIC_KEY","voting_account":"1.2.0","num_witness":0,"num_committee":0,"votes":[],"statistics":"2.7.0","whitelisting_accounts":[],"blacklisting_accounts":[]}]} API 0 is accessible using regular JSON-RPC: diff --git a/libraries/app/application.cpp b/libraries/app/application.cpp index bf381575..4310a616 100644 --- a/libraries/app/application.cpp +++ b/libraries/app/application.cpp @@ -58,11 +58,7 @@ namespace detail { auto nathan_key = fc::ecc::private_key::regenerate(fc::sha256::hash(string("nathan"))); dlog("Allocating all stake to ${key}", ("key", utilities::key_to_wif(nathan_key))); genesis_state_type initial_state; - /* - fc::reflector::visit( - fee_schedule_type::fee_set_visitor{initial_state.initial_parameters.current_fees, 0}); - */ - initial_state.initial_parameters.current_fees.set_all_fees(0); + initial_state.initial_parameters.current_fees.set_all_fees(GRAPHENE_BLOCKCHAIN_PRECISION); secret_hash_type::encoder enc; fc::raw::pack(enc, nathan_key); fc::raw::pack(enc, secret_hash_type()); diff --git a/libraries/chain/address.cpp b/libraries/chain/address.cpp index cb83a226..8ac6a127 100644 --- a/libraries/chain/address.cpp +++ b/libraries/chain/address.cpp @@ -29,12 +29,20 @@ namespace graphene { { FC_ASSERT( is_valid( base58str ) ); std::string prefix( GRAPHENE_ADDRESS_PREFIX ); + + // TODO: This is temporary for testing + if( is_valid( base58str, "BTS" ) ) prefix = std::string( "BTS" ); + std::vector v = fc::from_base58( base58str.substr( prefix.size() ) ); memcpy( (char*)addr._hash, v.data(), std::min( v.size()-4, sizeof( addr ) ) ); } bool address::is_valid( const std::string& base58str, const std::string& prefix ) { + // TODO: This is temporary for testing + if( prefix == GRAPHENE_ADDRESS_PREFIX && is_valid( base58str, "BTS" ) ) + return true; + const size_t prefix_len = prefix.size(); if( base58str.size() <= prefix_len ) return false; diff --git a/libraries/chain/db_init.cpp b/libraries/chain/db_init.cpp index 13558a51..10a68dd8 100644 --- a/libraries/chain/db_init.cpp +++ b/libraries/chain/db_init.cpp @@ -459,6 +459,6 @@ void database::init_genesis(const genesis_state_type& genesis_state) }); _undo_db.enable(); -} FC_CAPTURE_AND_RETHROW((genesis_state)) } +} FC_CAPTURE_AND_RETHROW(()) } } } diff --git a/libraries/chain/db_witness_schedule.cpp b/libraries/chain/db_witness_schedule.cpp index 5095ac1b..a6d82bf6 100644 --- a/libraries/chain/db_witness_schedule.cpp +++ b/libraries/chain/db_witness_schedule.cpp @@ -106,6 +106,8 @@ void database::update_witness_schedule(signed_block next_block) // triggering FC_ASSERT elsewhere assert( schedule_slot > 0 ); + witness_id_type first_witness; + bool slot_is_near = wso.scheduler.get_slot( schedule_slot-1, first_witness ); witness_id_type wit; @@ -119,13 +121,21 @@ void database::update_witness_schedule(signed_block next_block) witness_scheduler_rng rng(wso.rng_seed.data, _wso.slots_since_genesis); _wso.scheduler._min_token_count = std::max(int(gpo.active_witnesses.size()) / 2, 1); - uint32_t drain = schedule_slot; - while( drain > 0 ) + + if( slot_is_near ) { - if( _wso.scheduler.size() == 0 ) - break; - _wso.scheduler.consume_schedule(); - --drain; + uint32_t drain = schedule_slot; + while( drain > 0 ) + { + if( _wso.scheduler.size() == 0 ) + break; + _wso.scheduler.consume_schedule(); + --drain; + } + } + else + { + _wso.scheduler.reset_schedule( first_witness ); } while( !_wso.scheduler.get_slot(schedule_needs_filled, wit) ) { diff --git a/libraries/chain/include/graphene/chain/types.hpp b/libraries/chain/include/graphene/chain/types.hpp index e51b6c46..d783d4e7 100644 --- a/libraries/chain/include/graphene/chain/types.hpp +++ b/libraries/chain/include/graphene/chain/types.hpp @@ -438,6 +438,9 @@ namespace graphene { namespace chain { friend bool operator == ( const public_key_type& p1, const fc::ecc::public_key& p2); friend bool operator == ( const public_key_type& p1, const public_key_type& p2); friend bool operator != ( const public_key_type& p1, const public_key_type& p2); + + // TODO: This is temporary for testing + bool is_valid_v1( const std::string& base58str ); }; struct chain_parameters diff --git a/libraries/chain/include/graphene/chain/witness_scheduler.hpp b/libraries/chain/include/graphene/chain/witness_scheduler.hpp index 77f67478..ec595922 100644 --- a/libraries/chain/include/graphene/chain/witness_scheduler.hpp +++ b/libraries/chain/include/graphene/chain/witness_scheduler.hpp @@ -313,6 +313,40 @@ class generic_witness_scheduler return true; } + /** + * Reset the schedule, then re-schedule the given witness as the + * first witness. + */ + void reset_schedule( WitnessID first_witness ) + { + _schedule.clear(); + for( const WitnessID& wid : _ineligible_no_turn ) + { + _eligible.push_back( wid ); + } + _turns += _ineligible_no_turn.size(); + _ineligible_no_turn.clear(); + for( const auto& item : _ineligible_waiting_for_token ) + { + _eligible.push_back( item.first ); + _turns += (item.second ? 0 : 1); + } + _tokens += _ineligible_waiting_for_token.size(); + _ineligible_waiting_for_token.clear(); + if( debug ) check_invariant(); + + auto it = std::find( _eligible.begin(), _eligible.end(), first_witness ); + assert( it != _eligible.end() ); + + _schedule.push_back( *it ); + _ineligible_waiting_for_token.emplace_back( *it, false ); + _eligible.erase( it ); + _turns--; + _tokens--; + if( debug ) check_invariant(); + return; + } + // keep track of total turns / tokens in existence CountType _turns = 0; CountType _tokens = 0; diff --git a/libraries/chain/operations.cpp b/libraries/chain/operations.cpp index fb83aad7..aec48d76 100644 --- a/libraries/chain/operations.cpp +++ b/libraries/chain/operations.cpp @@ -187,11 +187,9 @@ share_type account_create_operation::calculate_fee( const fee_schedule_type& sch uint32_t s = name.size(); if( is_cheap_name(name) ) - s = 63; + s = 8; - FC_ASSERT( s >= 2 ); - - if( s >= 8 && s < 63 ) + if( s >= 8 ) core_fee_required = schedule.account_len8up_fee; else if( s == 7 ) core_fee_required = schedule.account_len7_fee; @@ -203,7 +201,7 @@ share_type account_create_operation::calculate_fee( const fee_schedule_type& sch core_fee_required = schedule.account_len4_fee; else if( s == 3 ) core_fee_required = schedule.account_len3_fee; - else if( s == 2 ) + else if( s <= 2 ) core_fee_required = schedule.account_len2_fee; // Authorities and vote lists can be arbitrarily large, so charge a data fee for big ones diff --git a/libraries/chain/types.cpp b/libraries/chain/types.cpp index a57dbe6d..b0fe691c 100644 --- a/libraries/chain/types.cpp +++ b/libraries/chain/types.cpp @@ -38,6 +38,17 @@ namespace graphene { namespace chain { // TODO: Refactor syntactic checks into static is_valid() // to make public_key_type API more similar to address API std::string prefix( GRAPHENE_ADDRESS_PREFIX ); + + // TODO: This is temporary for testing + try + { + if( is_valid_v1( base58str ) ) + prefix = std::string( "BTS" ); + } + catch( ... ) + { + } + const size_t prefix_len = prefix.size(); FC_ASSERT( base58str.size() > prefix_len ); FC_ASSERT( base58str.substr( 0, prefix_len ) == prefix , "", ("base58str", base58str) ); @@ -47,6 +58,20 @@ namespace graphene { namespace chain { FC_ASSERT( fc::ripemd160::hash( key_data.data, key_data.size() )._hash[0] == bin_key.check ); }; + // TODO: This is temporary for testing + bool public_key_type::is_valid_v1( const std::string& base58str ) + { + std::string prefix( "BTS" ); + const size_t prefix_len = prefix.size(); + FC_ASSERT( base58str.size() > prefix_len ); + FC_ASSERT( base58str.substr( 0, prefix_len ) == prefix , "", ("base58str", base58str) ); + auto bin = fc::from_base58( base58str.substr( prefix_len ) ); + auto bin_key = fc::raw::unpack(bin); + fc::ecc::public_key_data key_data = bin_key.data; + FC_ASSERT( fc::ripemd160::hash( key_data.data, key_data.size() )._hash[0] == bin_key.check ); + return true; + } + public_key_type::operator fc::ecc::public_key_data() const { return key_data; diff --git a/tests/tests/operation_tests2.cpp b/tests/tests/operation_tests2.cpp index b72688ed..c5edce81 100644 --- a/tests/tests/operation_tests2.cpp +++ b/tests/tests/operation_tests2.cpp @@ -467,7 +467,6 @@ BOOST_AUTO_TEST_CASE( witness_create ) generator_helper h = std::for_each(near_witnesses.begin(), near_witnesses.end(), generator_helper{*this, nathan_witness_id, nathan_private_key, false}); BOOST_CHECK(h.nathan_generated_block); - generate_block(0, nathan_private_key); } FC_LOG_AND_RETHROW() } /**