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:
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:

View file

@ -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<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);
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());

View file

@ -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<char> v = fc::from_base58( base58str.substr( prefix.size() ) );
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 )
{
// 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;

View file

@ -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(()) }
} }

View file

@ -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) )
{

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 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

View file

@ -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;

View file

@ -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

View file

@ -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<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
{
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{*this, nathan_witness_id, nathan_private_key, false});
BOOST_CHECK(h.nathan_generated_block);
generate_block(0, nathan_private_key);
} FC_LOG_AND_RETHROW() }
/**