提交 4bc5b4e8 编写于 作者: K Kevin Heifner 提交者: Matt Witherspoon

Merge pull request #979 from EOSIO/p2p-stat-271-gh916-2

P2p stat 271 gh916 2

(reapplied on noon branch)
上级 a01245f1
......@@ -4,11 +4,11 @@
Welcome to the EOS.IO source code repository! EOS.IO software enables developers to create and deploy
high-performance, horizontally scalable, blockchain infrastructure upon which decentralized applications
can be built.
can be built.
This code is currently alpha-quality and under rapid development. That said,
there is plenty early experimenters can do including, running a private multi-node test network and
develop applications (smart contracts).
develop applications (smart contracts).
# Resources
1. [EOS.IO Website](https://eos.io)
......@@ -58,7 +58,7 @@ For Ubuntu 16.10 and MacOS Sierra, there is an automated build script that can i
It is called build.sh with following inputs.
- architecture [ubuntu|darwin]
- optional mode [full|build]
- optional mode [full|build]
The second optional input can be full or build where full implies that it installs dependencies and builds eos. If you omit this input then build script always installs dependencies and then builds eos.
......@@ -68,13 +68,13 @@ The second optional input can be full or build where full implies that it instal
Clone EOS repository recursively as below and run build.sh located in root `eos` folder.
<a name="autoubuntu"></a>
#### Clean install Ubuntu 16.10
#### Clean install Ubuntu 16.10
```bash
git clone https://github.com/eosio/eos --recursive
cd eos
./build.sh ubuntu
./build.sh ubuntu
```
Now you can proceed to the next step - [Creating and launching a single-node testnet](#singlenode)
......@@ -99,10 +99,10 @@ cd eos
Now you can proceed to the next step - [Creating and launching a single-node testnet](#singlenode)
<a name="runanode"></a>
## Building EOS and running a node
## Building EOS and running a node
<a name="getcode"></a>
### Getting the code
### Getting the code
To download all of the code, download EOS source code and a recursion or two of submodules. The easiest way to get all of this is to do a recursive clone:
......@@ -117,7 +117,7 @@ git submodule update --init --recursive
```
<a name="build"></a>
### Building from source code
### Building from source code
The *WASM_LLVM_CONFIG* environment variable is used to find our recently built WASM compiler.
This is needed to compile the example contracts inside `eos/contracts` folder and their respective tests.
......@@ -146,7 +146,7 @@ EOS comes with a number of programs you can find in `~/eos/build/programs`. They
* launcher - application for nodes network composing and deployment; [more on launcher](https://github.com/EOSIO/eos/blob/master/testnet.md)
<a name="singlenode"></a>
### Creating and launching a single-node testnet
### Creating and launching a single-node testnet
After successfully building the project, the `eosd` binary should be present in the `build/programs/eosd` directory. Go ahead and run `eosd` -- it will probably exit with an error, but if not, close it immediately with <kbd>Ctrl-C</kbd>. Note that `eosd` created a directory named `data-dir` containing the default configuration (`config.ini`) and some other internals. This default data storage path can be overridden by passing `--data-dir /path/to/data` to `eosd`.
......@@ -203,7 +203,7 @@ When running `eosd` you should get log messages similar to below. It means the b
<a name="smartcontracts"></a>
## Example "Currency" Contract Walkthrough
EOS comes with example contracts that can be uploaded and run for testing purposes. Next we demonstrate how to upload and interact with the sample contract "currency".
EOS comes with example contracts that can be uploaded and run for testing purposes. Next we demonstrate how to upload and interact with the sample contract "currency".
<a name="smartcontractexample"></a>
### Example smart contracts
......@@ -216,7 +216,7 @@ cd ~/eos/build/programs/eosd/
```
<a name="walletimport"></a>
### Setting up a wallet and importing account key
### Setting up a wallet and importing account key
As you've previously added `plugin = eosio::wallet_api_plugin` into `config.ini`, EOS wallet will be running as a part of `eosd` process. Every contract requires an associated account, so first, create a wallet.
......@@ -225,7 +225,7 @@ cd ~/eos/build/programs/eosc/
./eosc wallet create # Outputs a password that you need to save to be able to lock/unlock the wallet
```
For the purpose of this walkthrough, import the private key of the `inita` account, a test account included within genesis.json, so that you're able to issue API commands under authority of an existing account. The private key referenced below is found within your `config.ini` and is provided to you for testing purposes.
For the purpose of this walkthrough, import the private key of the `inita` account, a test account included within genesis.json, so that you're able to issue API commands under authority of an existing account. The private key referenced below is found within your `config.ini` and is provided to you for testing purposes.
```bash
./eosc wallet import 5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3
......@@ -255,7 +255,7 @@ Save the values for future reference.
Run the `create` command where `inita` is the account authorizing the creation of the `currency` account and `PUBLIC_KEY_1` and `PUBLIC_KEY_2` are the values generated by the `create key` command
```bash
./eosc create account inita currency PUBLIC_KEY_1 PUBLIC_KEY_2
./eosc create account inita currency PUBLIC_KEY_1 PUBLIC_KEY_2
```
You should then get a json response back with a transaction ID confirming it was executed successfully.
......@@ -285,12 +285,12 @@ Now import the active private key generated previously in the wallet:
```
<a name="uploadsmartcontract"></a>
### Upload sample "currency" contract to blockchain
### Upload sample "currency" contract to blockchain
Before uploading a contract, verify that there is no current contract:
```bash
./eosc get code currency
./eosc get code currency
code hash: 0000000000000000000000000000000000000000000000000000000000000000
```
......@@ -328,11 +328,11 @@ Next verify the currency contract has the proper initial balance:
```
<a name="pushamessage"></a>
### Transfering funds with the sample "currency" contract
### Transfering funds with the sample "currency" contract
Anyone can send any message to any contract at any time, but the contracts may reject messages which are not given necessary permission. Messages are not
sent "from" anyone, they are sent "with permission of" one or more accounts and permission levels. The following commands shows a "transfer" message being
sent to the "currency" contract.
sent to the "currency" contract.
The content of the message is `'{"from":"currency","to":"inita","amount":50}'`. In this case we are asking the currency contract to transfer funds from itself to
someone else. This requires the permission of the currency contract.
......@@ -356,14 +356,14 @@ As a confirmation of a successfully submitted transaction you will receive json
<a name="readingcontract"></a>
### Reading sample "currency" contract balance
So now check the state of both of the accounts involved in the previous transaction.
So now check the state of both of the accounts involved in the previous transaction.
```bash
./eosc get table inita currency account
{
"rows": [{
"account": "account",
"balance": 50
"balance": 50
}
],
"more": false
......@@ -379,10 +379,10 @@ So now check the state of both of the accounts involved in the previous transact
}
```
As expected, the receiving account **inita** now has a balance of **50** tokens, and the sending account now has **50** less tokens than its initial supply.
As expected, the receiving account **inita** now has a balance of **50** tokens, and the sending account now has **50** less tokens than its initial supply.
<a name="localtestnet"></a>
## Running multi-node local testnet
## Running multi-node local testnet
To run a local testnet you can use a `launcher` application provided in `~/eos/build/programs/launcher` folder.
......@@ -399,9 +399,6 @@ This command will generate 2 data folders for each instance of the node: `tn_dat
You should see a following response:
```bash
adding hostname ip-XXX-XXX-XXX
found interface 127.0.0.1
found interface XXX.XX.XX.XX
spawning child, programs/eosd/eosd --skip-transaction-signatures --data-dir tn_data_0
spawning child, programs/eosd/eosd --skip-transaction-signatures --data-dir tn_data_1
```
......@@ -418,12 +415,12 @@ For each you should get a json with a blockchain information.
You can read more on launcher and its settings [here](https://github.com/EOSIO/eos/blob/master/testnet.md)
<a name="doxygen"></a>
## Doxygen documentation
## Doxygen documentation
You can find more detailed API documentation in Doxygen reference: https://eosio.github.io/eos/
<a name="docker"></a>
## Running EOS in Docker
## Running EOS in Docker
You can find up to date information about EOS Docker in the [Docker Readme](https://github.com/EOSIO/eos/blob/master/Docker/README.md)
......@@ -447,7 +444,7 @@ Dependencies:
* [binaryen](https://github.com/WebAssembly/binaryen.git)
<a name="ubuntu"></a>
### Clean install Ubuntu 16.10
### Clean install Ubuntu 16.10
Install the development toolkit:
......@@ -476,7 +473,7 @@ source ~/.bash_profile
```
Install [secp256k1-zkp (Cryptonomex branch)](https://github.com/cryptonomex/secp256k1-zkp.git):
```bash
cd ~
git clone https://github.com/cryptonomex/secp256k1-zkp.git
......@@ -520,10 +517,10 @@ cmake -G "Unix Makefiles" -DCMAKE_INSTALL_PREFIX=.. -DLLVM_TARGETS_TO_BUILD= -DL
make -j4 install
```
Your environment is set up. Now you can <a href="#runanode">build EOS and run a node</a>.
Your environment is set up. Now you can <a href="#runanode">build EOS and run a node</a>.
<a name="macos"></a>
### MacOS Sierra 10.12.6
### MacOS Sierra 10.12.6
macOS additional Dependencies:
......@@ -550,7 +547,7 @@ brew install git automake libtool boost openssl llvm@4 gmp
```
Install [secp256k1-zkp (Cryptonomex branch)](https://github.com/cryptonomex/secp256k1-zkp.git):
```bash
cd ~
git clone https://github.com/cryptonomex/secp256k1-zkp.git
......
......@@ -44,7 +44,8 @@ namespace eosio {
bad_transaction, ///< the peer sent a transaction that failed verification
validation, ///< the peer sent a block that failed validation
benign_other, ///< reasons such as a timeout. not fatal but warrant resetting
fatal_other ///< a catch-all for errors we don't have discriminated
fatal_other, ///< a catch-all for errors we don't have discriminated
authentication ///< peer failed authenicatio
};
constexpr auto reason_str( go_away_reason rsn ) {
......@@ -58,6 +59,7 @@ namespace eosio {
case unlinkable : return "unlinkable block received";
case bad_transaction : return "bad transaction";
case validation : return "invalid block";
case authentication : return "authentication failure";
case fatal_other : return "some other failure";
case benign_other : return "some other non-fatal condition";
default : return "some crazy reason";
......@@ -101,6 +103,7 @@ namespace eosio {
template<typename T>
struct select_ids {
select_ids () : mode(none),pending(0),ids() {}
id_list_modes mode;
uint32_t pending;
vector<T> ids;
......@@ -111,11 +114,13 @@ namespace eosio {
using ordered_blk_ids = select_ids<block_id_type>;
struct notice_message {
notice_message () : known_trx(), known_blocks() {}
ordered_txn_ids known_trx;
ordered_blk_ids known_blocks;
};
struct request_message {
request_message () : req_trx(), req_blocks() {}
ordered_txn_ids req_trx;
ordered_blk_ids req_blocks;
};
......
......@@ -177,7 +177,6 @@ namespace eosio {
int started_sessions = 0;
node_transaction_index local_txns;
ordered_txn_ids pending_notify;
shared_ptr<tcp::resolver> resolver;
......@@ -287,7 +286,7 @@ namespace eosio {
constexpr auto def_txn_expire_wait = std::chrono::seconds(3);
constexpr auto def_resp_expected_wait = std::chrono::seconds(1);
constexpr auto def_sync_fetch_span = 100;
constexpr auto def_max_just_send = 1300 * 3; // "mtu" * 3
constexpr auto def_max_just_send = 1500 * 3; // "mtu" * 3
constexpr auto def_send_whole_blocks = true;
constexpr auto message_header_size = 4;
......@@ -663,7 +662,6 @@ namespace eosio {
if(response_expected) {
response_expected->cancel();
}
ilog("calling reset");
pending_message_buffer.reset();
}
......@@ -879,7 +877,7 @@ namespace eosio {
}
void connection::cancel_sync(go_away_reason reason) {
elog("cancel sync reason = ${m}, out queue size ${o} ", ("m",reason_str(reason)) ("o", out_queue.size()));
fc_dlog(logger,"cancel sync reason = ${m}, out queue size ${o} ", ("m",reason_str(reason)) ("o", out_queue.size()));
sync_receiving.reset();
flush_queues();
switch (reason) {
......@@ -895,7 +893,7 @@ namespace eosio {
}
void connection::cancel_fetch() {
enqueue( ( request_message ) {ordered_txn_ids( ), ordered_blk_ids( )} );
enqueue( request_message() );
}
bool connection::enqueue_sync_block() {
......@@ -1192,7 +1190,7 @@ namespace eosio {
if( end > sync_known_lib_num )
end = sync_known_lib_num;
if( end > 0 && end >= start ) {
fc_dlog(logger, "conn ${n} recv blks ${s} to ${e}",("n",source->peer_name() )("s",start)("e",end));
fc_dlog(logger,"conn ${n} recv blks ${s} to ${e}",("n",source->peer_name() )("s",start)("e",end));
source->sync_receiving.reset(new sync_state( start, end, sync_last_requested_num ) );
}
}
......@@ -1202,6 +1200,8 @@ namespace eosio {
}
if(source->sync_receiving && source->sync_receiving->start_block == head_block + 1) {
fc_dlog(logger, "conn ${n} requesting range ${rs} to ${re} should be ${s} to ${e}",
("n",source->peer_name())("rs",source->sync_receiving->start_block)("re",source->sync_receiving->end_block)("s",start)("e",end));
source->enqueue( (sync_request_message){source->sync_receiving->start_block,
source->sync_receiving->end_block});
sync_last_requested_num = source->sync_receiving->end_block;
......@@ -1210,7 +1210,7 @@ namespace eosio {
void sync_manager::take_chunk( connection_ptr c) {
if( !c->sync_receiving) {
elog( "take_chunk called, but sync_receiving is empty");
fc_dlog(logger, "take_chunk called, but sync_receiving is empty");
return;
}
sync_state_ptr ss;
......@@ -1271,24 +1271,32 @@ namespace eosio {
fc_dlog( logger, "Skipping connect due to go_away reason ${r}",("r", reason_str( c->no_retry )));
return;
}
auto host = c->peer_addr.substr( 0, c->peer_addr.find(':') );
auto port = c->peer_addr.substr( host.size()+1, host.size() );
idump((host)(port));
tcp::resolver::query query( tcp::v4(), host.c_str(), port.c_str() );
// Note: need to add support for IPv6 too
resolver->async_resolve( query,
[c, this]( const boost::system::error_code& err,
tcp::resolver::iterator endpoint_itr ){
if( !err ) {
connect( c, endpoint_itr );
} else {
elog( "Unable to resolve ${peer_addr}: ${error}",
( "peer_addr", c->peer_name() )("error", err.message() ) );
}
});
auto colon = c->peer_addr.find(':');
if (colon == std::string::npos || colon == 0) {
elog ("Invalid peer address. must be \"host:port\": ${p}", ("p",c->peer_addr));
return;
}
auto host = c->peer_addr.substr( 0, colon );
auto port = c->peer_addr.substr( colon + 1);
idump((host)(port));
tcp::resolver::query query( tcp::v4(), host.c_str(), port.c_str() );
// Note: need to add support for IPv6 too
resolver->async_resolve( query,
[c, this]( const boost::system::error_code& err,
tcp::resolver::iterator endpoint_itr ){
if( !err ) {
connect( c, endpoint_itr );
} else {
elog( "Unable to resolve ${peer_addr}: ${error}",
( "peer_addr", c->peer_name() )("error", err.message() ) );
}
});
}
void net_plugin_impl::connect( connection_ptr c, tcp::resolver::iterator endpoint_itr ) {
if( c->no_retry != go_away_reason::no_reason) {
string rsn = reason_str(c->no_retry);
......@@ -1302,6 +1310,7 @@ namespace eosio {
( const boost::system::error_code& err ) {
if( !err ) {
start_session( c );
c->send_handshake ();
} else {
if( endpoint_itr != tcp::resolver::iterator() ) {
c->close();
......@@ -1322,7 +1331,6 @@ namespace eosio {
con->socket->set_option( nodelay );
start_read_message( con );
++started_sessions;
con->send_handshake();
// for now, we can just use the application main loop.
// con->readloop_complete = bf::async( [=](){ read_loop( con ); } );
......@@ -1450,12 +1458,16 @@ namespace eosio {
void net_plugin_impl::handle_message( connection_ptr c, const handshake_message &msg) {
ilog("got a handshake_message from ${p} ${h}", ("p",c->peer_addr)("h",msg.p2p_address));
chain_controller& cc = chain_plug->chain();
uint32_t lib_num = cc.last_irreversible_block_num( );
uint32_t peer_lib = msg.last_irreversible_block_num;
if( c->connecting ) {
c->connecting = false;
}
if (msg.generation == 1) {
if( msg.node_id == node_id) {
elog( "Self connection detected. Closing connection");
c->enqueue( go_away_message( go_away_reason::self ) );
c->enqueue( go_away_message( self ) );
return;
}
......@@ -1464,13 +1476,12 @@ namespace eosio {
for(const auto &check : connections) {
if(check == c)
continue;
if(check->connected() &&
check->peer_name() == msg.p2p_address) {
if(check->connected() && check->peer_name() == msg.p2p_address) {
fc_dlog(logger, "sending go_away duplicate to ${ep}", ("ep",msg.p2p_address) );
go_away_message gam(go_away_reason::duplicate);
gam.node_id = node_id;
c->enqueue(gam);
c->no_retry = go_away_reason::duplicate;
c->no_retry = duplicate;
return;
}
}
......@@ -1488,7 +1499,7 @@ namespace eosio {
if (network_version_match) {
elog("Peer network version does not match expected ${nv} but got ${mnv}",
("nv", network_version)("mnv", msg.network_version));
c->enqueue(go_away_message(go_away_reason::wrong_version));
c->enqueue(go_away_message(wrong_version));
return;
} else {
wlog("Peer network version does not match expected ${nv} but got ${mnv}",
......@@ -1501,41 +1512,109 @@ namespace eosio {
}
if(!authenticate_peer(msg)) {
dlog("Peer not authenticated. Closing connection.");
close(c);
elog("Peer not authenticated. Closing connection.");
c->enqueue(go_away_message(authentication));
return;
}
}
chain_controller& cc = chain_plug->chain();
uint32_t lib_num = cc.last_irreversible_block_num( );
uint32_t peer_lib = msg.last_irreversible_block_num;
bool on_fork = false;
fc_dlog(logger, "lib_num = ${ln} peer_lib = ${pl}",("ln",lib_num)("pl",peer_lib));
bool on_fork = false;
fc_dlog(logger, "lib_num = ${ln} peer_lib = ${pl}",("ln",lib_num)("pl",peer_lib));
if( peer_lib <= lib_num && peer_lib > 0) {
try {
block_id_type peer_lib_id = cc.get_block_id_for_num( peer_lib);
on_fork =( msg.last_irreversible_block_id != peer_lib_id);
}
catch( ...) {
wlog( "caught an exception getting block id for ${pl}",("pl",peer_lib));
on_fork = true;
}
if( on_fork) {
elog( "Peer chain is forked");
c->enqueue( go_away_message( go_away_reason::forked ));
return;
if( peer_lib <= lib_num && peer_lib > 0) {
try {
block_id_type peer_lib_id = cc.get_block_id_for_num( peer_lib);
on_fork =( msg.last_irreversible_block_id != peer_lib_id);
}
catch( ...) {
wlog( "caught an exception getting block id for ${pl}",("pl",peer_lib));
on_fork = true;
}
if( on_fork) {
elog( "Peer chain is forked");
c->enqueue( go_away_message( forked ));
return;
}
}
if (c->sent_handshake_count == 0) {
c->send_handshake();
}
}
c->last_handshake = msg;
sync_master->reset_lib_num();
c->syncing = false;
//--------------------------------
// sync need checkz;
//
// 0. my head block id == peer head id means we are all caugnt up block wize
// 1. my lib < peer lib - start sync locally
// 2. my lib > peer lib - send an last_irr_catch_up notice if not the first generation
//
// 3 my head block num <= peer head block num - update sync state and send a catchup request
// 4 my head block num > peer block num ssend a notice catchup if this is not the first generation
//
//-----------------------------
uint32_t head = cc.head_block_num( );
block_id_type head_id = cc.head_block_id();
if (sync_master->syncing() ) {
fc_dlog(logger, "sync check state -1");
sync_master->start_sync( c, peer_lib);
return;
}
if (head_id == msg.head_id) {
fc_dlog(logger, "sync check state 0");
notice_message note;
note.known_blocks.mode = none;
note.known_trx.mode = catch_up;
note.known_trx.pending = local_txns.size();
c->enqueue( note );
return;
}
if (lib_num < peer_lib) {
fc_dlog(logger, "sync check state 1");
sync_master->start_sync( c, peer_lib);
return;
}
if (lib_num > peer_lib ) {
fc_dlog(logger, "sync check state 2");
if ( msg.generation > 1 ) {
notice_message note;
note.known_trx.mode = none;
note.known_blocks.mode = last_irr_catch_up;
note.known_blocks.pending = lib_num;
c->enqueue( note );
}
c->syncing = true;
return;
}
if (head <= msg.head_num ) {
fc_dlog(logger, "sync check state 3");
request_message req;
req.req_trx.mode = none;
req.req_blocks.mode = catch_up;
req.req_blocks.pending = lib_num;
c->enqueue( req );
return;
}
else {
fc_dlog(logger, "sync check state 4");
if ( msg.generation > 1 ) {
notice_message note;
note.known_trx.mode = none;
note.known_blocks.mode = catch_up;
note.known_blocks.pending = head - lib_num;
c->enqueue( note );
}
c->syncing = true;
return;
}
elog ("sync check failed to resolbe status");
return;
#if 0
if( peer_lib > head || sync_master->syncing() ) {
sync_master->start_sync( c, peer_lib );
}
......@@ -1543,23 +1622,26 @@ namespace eosio {
fc_dlog(logger, "msg.head_id = ${m} our head = ${h}",("m",msg.head_id)("h",head_id));
notice_message note;
note.known_blocks.mode = id_list_modes::none;
note.known_blocks.mode = none;
fc_dlog(logger, "msg head = ${mh} msg lib = ${ml} my head = ${h} my lib = ${l}",("mh",msg.head_num)("ml",msg.last_irreversible_block_num)("h",head)("l",lib_num));
if( msg.head_num >= lib_num ) {
note.known_blocks.mode = id_list_modes::catch_up;
note.known_blocks.mode = catch_up;
note.known_blocks.pending = head - lib_num;
} else {
note.known_blocks.mode = id_list_modes::last_irr_catch_up;
note.known_blocks.mode = last_irr_catch_up;
note.known_blocks.pending = lib_num;
}
note.known_trx.mode = id_list_modes::catch_up;
note.known_trx.pending = local_txns.size(); // cc.pending().size();
note.known_trx.mode = catch_up;
note.known_trx.pending = local_txns.size();
if( note.known_trx.pending > 0 || note.known_blocks.pending > 0) {
fc_dlog(logger, "sending ${m} notice to ${n} about ${t} txns and ${b} blocks",("m",modes_str(note.known_blocks.mode))("n",c->peer_name())("t",note.known_trx.pending)("b",note.known_blocks.pending));
c->enqueue( note );
if (msg.generation > 1 && note.known_blocks.mode == catch_up) {
fc_dlog(logger, "sending ${m} notice to ${n} about ${t} txns and ${b} blocks",("m",modes_str(note.known_blocks.mode))("n",c->peer_name())("t",note.known_trx.pending)("b",note.known_blocks.pending));
c->enqueue( note );
}
c->syncing = true;
}
}
#endif
}
void net_plugin_impl::handle_message( connection_ptr c, const go_away_message &msg ) {
......@@ -1614,16 +1696,17 @@ namespace eosio {
bool send_req = false;
chain_controller &cc = chain_plug->chain();
switch (msg.known_trx.mode) {
case id_list_modes::none:
case id_list_modes::last_irr_catch_up: {
req.req_trx.mode = id_list_modes::none;
fwd.known_trx.mode = id_list_modes::none;
case none:
break;
case last_irr_catch_up: {
req.req_trx.mode = none;
fwd.known_trx.mode = none;
break;
}
case id_list_modes::catch_up : {
case catch_up : {
if( msg.known_trx.pending > 0) {
// plan to get all except what we already know about.
req.req_trx.mode = id_list_modes::catch_up;
req.req_trx.mode = catch_up;
send_req = true;
size_t known_sum = local_txns.size();
if( known_sum ) {
......@@ -1634,10 +1717,10 @@ namespace eosio {
}
break;
}
case id_list_modes::normal: {
fwd.known_trx.mode = id_list_modes::normal;
case normal: {
fwd.known_trx.mode = normal;
fwd.known_trx.pending = 0;
req.req_trx.mode = id_list_modes::normal;
req.req_trx.mode = normal;
req.req_trx.pending = 0;
for( const auto& t : msg.known_trx.ids ) {
const auto &tx = my_impl->local_txns.get<by_id>( ).find( t );
......@@ -1645,7 +1728,7 @@ namespace eosio {
if( tx == my_impl->local_txns.end( ) ) {
c->trx_state.insert( ( transaction_state ){ t,true,true,( uint32_t ) - 1,
fc::time_point( ),fc::time_point( ) } );
// my_impl->local_txns.insert();
if( !sync_master->syncing( ) ) {
fwd.known_trx.ids.push_back( t );
}
......@@ -1658,27 +1741,26 @@ namespace eosio {
fc_dlog(logger,"this is a ${m} notice with ${n} blocks", ("m",modes_str(msg.known_blocks.mode))("n",msg.known_blocks.pending));
switch (msg.known_blocks.mode) {
case id_list_modes::none : {
if (msg.known_trx.mode != id_list_modes::normal) {
case none : {
if (msg.known_trx.mode != normal) {
return;
}
break;
}
case id_list_modes::last_irr_catch_up : {
if (!c->sync_receiving) {
case last_irr_catch_up : {
if (!c->sync_receiving ) {
sync_master->start_sync(c, msg.known_blocks.pending);
}
break;
}
case id_list_modes::catch_up : {
req.req_blocks.mode = id_list_modes::catch_up;
case catch_up : {
req.req_blocks.mode = catch_up;
req.req_blocks.pending = msg.known_blocks.pending;
send_req = true;
break;
}
case id_list_modes::normal : {
case normal : {
req.req_blocks.mode = normal;
for( const auto& blkid : msg.known_blocks.ids) {
optional<signed_block> b;
......@@ -1700,20 +1782,19 @@ namespace eosio {
break;
}
default: {
elog( "received a bogus known_blocks.mode ${m} from ${p}",("m",static_cast<uint32_t>(msg.known_blocks.mode))("p",c->peer_name()));
close(c);
fc_dlog(logger, "received a bogus known_blocks.mode ${m} from ${p}",("m",static_cast<uint32_t>(msg.known_blocks.mode))("p",c->peer_name()));
}
}
if (fwd.known_trx.mode == id_list_modes::normal ||
fwd.known_blocks.mode == id_list_modes::normal) {
if (fwd.known_trx.mode == normal ||
fwd.known_blocks.mode == normal) {
for (auto &conn : my_impl->connections) {
if (conn->syncing || conn == c) {
continue;
}
notice_message to_peer;
to_peer.known_trx.mode = fwd.known_trx.mode;
if (fwd.known_trx.mode == id_list_modes::normal) {
if (fwd.known_trx.mode == normal) {
for (const auto &t : fwd.known_trx.ids) {
const auto &tx = conn->trx_state.get<by_id>( ).find( t );
if( tx == conn->trx_state.end( ) ) {
......@@ -1723,11 +1804,11 @@ namespace eosio {
}
}
if (to_peer.known_trx.ids.empty()) {
to_peer.known_trx.mode = id_list_modes::none;
to_peer.known_trx.mode = none;
}
}
to_peer.known_blocks.mode = fwd.known_blocks.mode;
if (fwd.known_blocks.mode == id_list_modes::normal) {
if (fwd.known_blocks.mode == normal) {
for (const auto &bid : fwd.known_blocks.ids) {
const auto &blk = conn->block_state.get<by_id>( ).find( bid );
if( blk == conn->block_state.end( ) ) {
......@@ -1736,11 +1817,11 @@ namespace eosio {
}
}
if (to_peer.known_blocks.ids.empty()) {
to_peer.known_blocks.mode = id_list_modes::none;
to_peer.known_blocks.mode = none;
}
}
if (to_peer.known_trx.mode == id_list_modes::normal ||
to_peer.known_blocks.mode == id_list_modes::normal) {
if (to_peer.known_trx.mode == normal ||
to_peer.known_blocks.mode == normal) {
conn->enqueue (to_peer);
}
}
......@@ -1753,11 +1834,11 @@ namespace eosio {
void net_plugin_impl::handle_message( connection_ptr c, const request_message &msg) {
switch (msg.req_blocks.mode) {
case id_list_modes::catch_up :
case catch_up :
fc_dlog(logger, "got a catch_up request_message from ${p}", ("p",c->peer_name()));
c->blk_send_branch( msg.req_trx.ids );
break;
case id_list_modes::normal :
case normal :
fc_dlog(logger, "got a normal request_message from ${p}", ("p",c->peer_name()));
c->blk_send(msg.req_blocks.ids);
break;
......@@ -1766,14 +1847,14 @@ namespace eosio {
switch (msg.req_trx.mode) {
case id_list_modes::catch_up :
case catch_up :
c->txn_send_pending(msg.req_trx.ids);
break;
case id_list_modes::normal :
case normal :
c->txn_send(msg.req_trx.ids);
break;
case id_list_modes::none :
if(msg.req_blocks.mode == id_list_modes::none)
case none :
if(msg.req_blocks.mode == none)
c->stop_send();
break;
default:;
......@@ -1791,113 +1872,9 @@ namespace eosio {
}
}
void net_plugin_impl::handle_message( connection_ptr c, const block_summary_message &msg) {
void net_plugin_impl::handle_message( connection_ptr , const block_summary_message &) {
#if 0 // function is obsolete
fc_dlog(logger, "got a block_summary_message from ${p}", ("p",c->peer_name()));
fc_dlog(logger, "bsm header = ${h}",("h",msg.block_header));
fc_dlog(logger, "txn count = ${c}", ("c",msg.trx_ids.size()));
const auto& itr = c->block_state.get<by_id>();
auto bs = itr.find(msg.block_header.id());
if( bs == c->block_state.end()) {
c->block_state.insert( (block_state){msg.block_header.id(),true,true,fc::time_point()});
send_all( msg, [c](connection_ptr cptr) -> bool {
return cptr != c;
});
} else {
if( !bs->is_known) {
c->block_state.modify(bs, make_known());
send_all( msg, [c](connection_ptr cptr) -> bool {
return cptr != c;
});
}
}
signed_block sb;
bool fetch_error = false;
chain_controller &cc = chain_plug->chain();
if( !cc.is_known_block(msg.block_header.id()) ) {
sb.previous = msg.block_header.previous;
sb.timestamp = msg.block_header.timestamp;
sb.transaction_merkle_root = msg.block_header.transaction_merkle_root;
sb.producer_changes = msg.block_header.producer_changes;
sb.producer = msg.block_header.producer;
sb.producer_signature = msg.block_header.producer_signature;
for( auto &cyc : msg.trx_ids ) {
fc_dlog(logger, "cycle count = ${c}", ("c",cyc.size()));
if( cyc.size() == 0 ) {
continue;
}
sb.cycles.emplace_back( eosio::chain::cycle( ) );
eosio::chain::cycle &sbcycle = sb.cycles.back( );
for( auto &cyc_thr_id : cyc ) {
/*
fc_dlog(logger, "cycle user theads count = ${c}", ("c",cyc_thr_id.user_trx.size()));
if(cyc_thr_id.user_trx.size() == 0) {
continue;
}
sbcycle.emplace_back( eosio::chain::thread( ) );
eosio::chain::thread &cyc_thr = sbcycle.back();
for( auto &gt : cyc_thr_id.gen_trx ) {
try {
auto gen = cc.get_generated_transaction( gt );
cyc_thr.generated_input.push_back( processed_generated_transaction( gen ) );
} catch ( const exception &ex) {
fetch_error = true;
elog( "unable to retieve generated transaction, caught {ex}", ("ex",ex) );
break;
} catch ( ... ) {
fetch_error = true;
elog( "unable to retieve generated transaction" );
break;
}
}
*/
for( auto &ut : cyc_thr_id.user_trx ) {
// auto ltxn = local_txns.get<by_id>().find(ut);
try {
processed_transaction pt(cc.get_recent_transaction(ut.id));
pt.output = ut.outmsgs;
cyc_thr.user_input.emplace_back(pt);
fc_dlog(logger, "Found the transaction");
} catch ( const exception &ex) {
fetch_error = true;
elog( "unable to retieve user transaction, caught {ex}", ("ex",ex) );
break;
} catch ( ... ) {
fetch_error = true;
elog( "unable to retieve user transaction" );
break;
}
}
if( fetch_error ){
break;
}
}
if( fetch_error ){
break;
}
}
try {
fc_dlog(logger, "calling accept block, fetcherror = ${fe}",("fe",fetch_error));
if( !fetch_error )
chain_plug->accept_block( sb, false );
} catch( const unlinkable_block_exception &ex) {
elog( "caught unlinkable block exception #${n}",("n",sb.block_num()));
c->enqueue( go_away_message( go_away_reason::unlinkable ));
} catch( const assert_exception &ex) {
// received a block due to out of sequence
elog( "caught assertion on block #${n} ${ex}",
("n",sb.block_num())("ex",ex.what()));
} catch( ... ) {
elog( "unable to accept block, reason unknown" );
}
}
#endif
#endif
}
......@@ -2014,6 +1991,7 @@ namespace eosio {
elog( "unable to accept block on assert exception ${n} from ${p}",("n",ex.to_string())("p",c->peer_name()));
} catch( const fc::exception &ex) {
elog( "accept_block threw a non-assert exception ${x} from ${p}",( "x",ex.to_string())("p",c->peer_name()));
reason = no_reason;
} catch( ...) {
elog( "handle sync block caught something else from ${p}",("num",num)("p",c->peer_name()));
}
......@@ -2195,21 +2173,21 @@ namespace eosio {
});
}
else {
fc_dlog(logger, "pending_notify, mode = ${m}, pending count = ${p}",("m",modes_str(pending_notify.mode))("p",pending_notify.pending));
pending_notify.mode = normal;
pending_notify.ids.push_back( txnid );
notice_message nm = { pending_notify, ordered_blk_ids( ) };
send_all( nm, [txn, txnid](connection_ptr c) -> bool {
notice_message pending_notify;
pending_notify.known_trx.mode = normal;
pending_notify.known_trx.ids.push_back( txnid );
pending_notify.known_blocks.mode = none;
send_all(pending_notify, [txnid](connection_ptr c) -> bool {
const auto& bs = c->trx_state.find(txnid);
bool unknown = bs == c->trx_state.end();
if( unknown) {
fc_dlog(logger, "sending notice to ${n}", ("n",c->peer_name() ) );
c->trx_state.insert(transaction_state({txnid,false,true,(uint32_t)-1,
fc::time_point(),fc::time_point() }));
}
return unknown;
});
pending_notify.ids.clear();
}
}
......@@ -2221,59 +2199,29 @@ namespace eosio {
}
void net_plugin_impl::broadcast_block_impl( const chain::signed_block &sb) {
if( send_whole_blocks) {
net_message msg(sb);
uint32_t packsiz = fc::raw::pack_size(msg);
uint32_t msgsiz = packsiz + sizeof(packsiz);
if (msgsiz <= just_send_it_max) {
send_all( sb,[](connection_ptr c) -> bool { return true; });
return;
}
#if 0 //disabling block summary support
block_summary_message bsm = {sb, vector<cycle_ids>()};
vector<cycle_ids> &trxs = bsm.trx_ids;
if( !sb.cycles.empty()) {
for( const auto& cyc : sb.cycles) {
fc_dlog(logger, "cyc.size = ${cs}",( "cs", cyc.size()));
if( cyc.empty() ) {
continue;
}
trxs.emplace_back(cycle_ids());
cycle_ids &cycs = trxs.back();
fc_dlog(logger, "trxs.size = ${ts} cycles.size = ${cs}",("ts", trxs.size())("cs", cycs.size()));
for( const auto& thr : cyc) {
fc_dlog(logger, "user txns = ${ui} generated = ${gi}",("ui",thr.user_input.size( ))("gi",thr.generated_input.size( )));
if( thr.user_input.size( ) == 0 ) {
continue;
}
cycs.emplace_back(thread_ids());
thread_ids &thd_ids = cycs.back();
for( auto gi : thr.generated_input ) {
thd_ids.gen_trx.emplace_back( gi.id );
}
for( auto &ui : thr.user_input) {
processed_trans_summary pts({ui.id( ),ui.output });
thd_ids.user_trx.emplace_back( pts );
fc_dlog(logger, "user txn has ${m} messages, summary has ${ms}", ("m",ui.output.size())("ms",pts.outmsgs.size()));
else {
notice_message pending_notify;
block_id_type bid = sb.id();
pending_notify.known_blocks.mode = normal;
pending_notify.known_blocks.ids.push_back( bid );
pending_notify.known_trx.mode = none;
send_all(pending_notify, [bid](connection_ptr c) -> bool {
const auto& bs = c->block_state.find(bid);
bool unknown = bs == c->block_state.end();
if( unknown) {
fc_dlog(logger, "sending block notice to ${n}", ("n",c->peer_name() ) );
c->block_state.insert(block_state({bid,false,true,fc::time_point() }));
}
}
}
}
fc_dlog(logger, "sending bsm with ${c} transactions",("c",trxs.size()));
fc_dlog(logger, "bsm header = ${h} txns = ${t}",("h",bsm.block_header)("t",bsm.trx_ids.size()));
if(bsm.trx_ids.size() > 0) {
fc_dlog(logger, "cycles.size = ${cs}",("cs", bsm.trx_ids[0].size()));
if (bsm.trx_ids[0].size()) {
}
return unknown;
});
}
send_all( bsm,[sb](connection_ptr c) -> bool {
const auto& bs = c->block_state.find(sb.id());
if( bs == c->block_state.end()) {
c->block_state.insert( (block_state){sb.id(),true,true,fc::time_point()});
return true;
}
return false;
});
#endif
}
bool net_plugin_impl::authenticate_peer(const handshake_message& msg) const {
......@@ -2566,9 +2514,6 @@ namespace eosio {
my->keepalive_timer.reset(new boost::asio::steady_timer(app().get_io_service()));
my->ticker();
my->pending_notify.mode = id_list_modes::normal;
my->pending_notify.pending = 0;
}
void net_plugin::plugin_startup() {
......@@ -2625,9 +2570,10 @@ namespace eosio {
return "already connected";
connection_ptr c = std::make_shared<connection>(host);
fc_dlog(my->logger,"adding new connection to the list");
my->connections.insert( c );
fc_dlog(my->logger,"calling active connector");
my->connect( c );
return "added connection";
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册