This commit is contained in:
Daniel Larimer 2015-07-06 16:55:28 -04:00
commit 7d6d7066c2
10 changed files with 101 additions and 23 deletions

View file

@ -8,7 +8,7 @@ Starting Graphene
For Ubuntu 14.04 LTS users, see this link first: For Ubuntu 14.04 LTS users, see this link first:
https://github.com/cryptonomex/graphene/wiki/build-ubuntu https://github.com/cryptonomex/graphene/wiki/build-ubuntu
and then proceed with: and then proceed with:
git clone https://github.com/cryptonomex/graphene.git git clone https://github.com/cryptonomex/graphene.git
@ -18,7 +18,9 @@ and then proceed with:
make make
./programs/witness_node/witness_node ./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 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. 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 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. 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 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: 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 $ 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: API 0 is accessible using regular JSON-RPC:

View file

@ -58,11 +58,7 @@ namespace detail {
auto nathan_key = fc::ecc::private_key::regenerate(fc::sha256::hash(string("nathan"))); 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))); dlog("Allocating all stake to ${key}", ("key", utilities::key_to_wif(nathan_key)));
genesis_state_type initial_state; genesis_state_type initial_state;
/* initial_state.initial_parameters.current_fees.set_all_fees(GRAPHENE_BLOCKCHAIN_PRECISION);
fc::reflector<fee_schedule_type>::visit(
fee_schedule_type::fee_set_visitor{initial_state.initial_parameters.current_fees, 0});
*/
initial_state.initial_parameters.current_fees.set_all_fees(0);
secret_hash_type::encoder enc; secret_hash_type::encoder enc;
fc::raw::pack(enc, nathan_key); fc::raw::pack(enc, nathan_key);
fc::raw::pack(enc, secret_hash_type()); fc::raw::pack(enc, secret_hash_type());

View file

@ -29,12 +29,20 @@ namespace graphene {
{ {
FC_ASSERT( is_valid( base58str ) ); FC_ASSERT( is_valid( base58str ) );
std::string prefix( GRAPHENE_ADDRESS_PREFIX ); std::string prefix( GRAPHENE_ADDRESS_PREFIX );
// TODO: This is temporary for testing
if( is_valid( base58str, "BTS" ) ) prefix = std::string( "BTS" );
std::vector<char> v = fc::from_base58( base58str.substr( prefix.size() ) ); std::vector<char> v = fc::from_base58( base58str.substr( prefix.size() ) );
memcpy( (char*)addr._hash, v.data(), std::min<size_t>( v.size()-4, sizeof( addr ) ) ); memcpy( (char*)addr._hash, v.data(), std::min<size_t>( v.size()-4, sizeof( addr ) ) );
} }
bool address::is_valid( const std::string& base58str, const std::string& prefix ) 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(); const size_t prefix_len = prefix.size();
if( base58str.size() <= prefix_len ) if( base58str.size() <= prefix_len )
return false; return false;

View file

@ -459,6 +459,6 @@ void database::init_genesis(const genesis_state_type& genesis_state)
}); });
_undo_db.enable(); _undo_db.enable();
} FC_CAPTURE_AND_RETHROW((genesis_state)) } } FC_CAPTURE_AND_RETHROW(()) }
} } } }

View file

@ -106,6 +106,8 @@ void database::update_witness_schedule(signed_block next_block)
// triggering FC_ASSERT elsewhere // triggering FC_ASSERT elsewhere
assert( schedule_slot > 0 ); 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; 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); 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); _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 ) uint32_t drain = schedule_slot;
break; while( drain > 0 )
_wso.scheduler.consume_schedule(); {
--drain; 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) ) while( !_wso.scheduler.get_slot(schedule_needs_filled, wit) )
{ {

View file

@ -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 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);
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 struct chain_parameters

View file

@ -313,6 +313,40 @@ class generic_witness_scheduler
return true; 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 // keep track of total turns / tokens in existence
CountType _turns = 0; CountType _turns = 0;
CountType _tokens = 0; CountType _tokens = 0;

View file

@ -187,11 +187,9 @@ share_type account_create_operation::calculate_fee( const fee_schedule_type& sch
uint32_t s = name.size(); uint32_t s = name.size();
if( is_cheap_name(name) ) if( is_cheap_name(name) )
s = 63; s = 8;
FC_ASSERT( s >= 2 ); if( s >= 8 )
if( s >= 8 && s < 63 )
core_fee_required = schedule.account_len8up_fee; core_fee_required = schedule.account_len8up_fee;
else if( s == 7 ) else if( s == 7 )
core_fee_required = schedule.account_len7_fee; 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; core_fee_required = schedule.account_len4_fee;
else if( s == 3 ) else if( s == 3 )
core_fee_required = schedule.account_len3_fee; core_fee_required = schedule.account_len3_fee;
else if( s == 2 ) else if( s <= 2 )
core_fee_required = schedule.account_len2_fee; core_fee_required = schedule.account_len2_fee;
// Authorities and vote lists can be arbitrarily large, so charge a data fee for big ones // Authorities and vote lists can be arbitrarily large, so charge a data fee for big ones

View file

@ -38,6 +38,17 @@ namespace graphene { namespace chain {
// TODO: Refactor syntactic checks into static is_valid() // TODO: Refactor syntactic checks into static is_valid()
// to make public_key_type API more similar to address API // to make public_key_type API more similar to address API
std::string prefix( GRAPHENE_ADDRESS_PREFIX ); 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(); const size_t prefix_len = prefix.size();
FC_ASSERT( base58str.size() > prefix_len ); FC_ASSERT( base58str.size() > prefix_len );
FC_ASSERT( base58str.substr( 0, prefix_len ) == prefix , "", ("base58str", base58str) ); 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 ); 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<binary_key>(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 public_key_type::operator fc::ecc::public_key_data() const
{ {
return key_data; return key_data;

View file

@ -467,7 +467,6 @@ BOOST_AUTO_TEST_CASE( witness_create )
generator_helper h = std::for_each(near_witnesses.begin(), near_witnesses.end(), generator_helper h = std::for_each(near_witnesses.begin(), near_witnesses.end(),
generator_helper{*this, nathan_witness_id, nathan_private_key, false}); generator_helper{*this, nathan_witness_id, nathan_private_key, false});
BOOST_CHECK(h.nathan_generated_block); BOOST_CHECK(h.nathan_generated_block);
generate_block(0, nathan_private_key);
} FC_LOG_AND_RETHROW() } } FC_LOG_AND_RETHROW() }
/** /**