Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions data/bn.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ threads = 0
protocol_maximum = 70013
# The minimum network protocol version, defaults to 31402.
protocol_minimum = 31402
# The services exposed by network connections, defaults to 1 (full node).
services = 1
# The services exposed by network connections, defaults to 9 (full node, witness).
services = 9
# The advertised services that cause a peer to be dropped, defaults to 0 (none).
invalid_services = 0
# The magic number for message headers, defaults to 3652501241 (use 118034699 for testnet).
Expand Down Expand Up @@ -156,6 +156,12 @@ bip68 = true
bip112 = true
# Use median time past for locktime, defaults to true (soft fork).
bip113 = true
# Segregated witness consensus layer, defaults to true (soft fork).
bip141 = true
# Version 0 transaction digest, defaults to true (soft fork).
bip143 = true
# Prevent dummy value malleability, defaults to true (soft fork).
bip147 = true

[node]
# The time to wait for a requested block, defaults to 60.
Expand Down
2 changes: 2 additions & 0 deletions include/bitcoin/node/protocols/protocol_block_in.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ class BCN_API protocol_block_in
const asio::duration block_latency_;
const bool headers_from_peer_;
const bool blocks_from_peer_;
const bool require_witness_;
const bool peer_witness_;

// This is protected by mutex.
hash_queue backlog_;
Expand Down
8 changes: 5 additions & 3 deletions include/bitcoin/node/protocols/protocol_block_out.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,11 @@ class BCN_API protocol_block_out

void send_next_data(inventory_ptr inventory);
void send_block(const code& ec, block_const_ptr message,
uint64_t height, inventory_ptr inventory);
size_t height, inventory_ptr inventory);
void send_merkle_block(const code& ec, merkle_block_const_ptr message,
uint64_t height, inventory_ptr inventory);
size_t height, inventory_ptr inventory);
void send_compact_block(const code& ec, compact_block_const_ptr message,
uint64_t height, inventory_ptr inventory);
size_t height, inventory_ptr inventory);

bool handle_receive_get_data(const code& ec,
get_data_const_ptr message);
Expand All @@ -76,11 +76,13 @@ class BCN_API protocol_block_out
block_const_ptr_list_const_ptr incoming,
block_const_ptr_list_const_ptr outgoing);

// These are thread safe.
full_node& node_;
blockchain::safe_chain& chain_;
bc::atomic<hash_digest> last_locator_top_;
std::atomic<bool> compact_to_peer_;
std::atomic<bool> headers_to_peer_;
const bool enable_witness_;
};

} // namespace node
Expand Down
5 changes: 4 additions & 1 deletion include/bitcoin/node/protocols/protocol_transaction_in.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,13 @@ class BCN_API protocol_transaction_in

void handle_stop(const code&);

// These are thread safe.
blockchain::safe_chain& chain_;
const uint64_t minimum_relay_fee_;
const bool relay_from_peer_;
const bool refresh_pool_;
const uint64_t minimum_relay_fee_;
const bool require_witness_;
const bool peer_witness_;
};

} // namespace node
Expand Down
6 changes: 4 additions & 2 deletions include/bitcoin/node/protocols/protocol_transaction_out.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ class BCN_API protocol_transaction_out

private:
void send_next_data(inventory_ptr inventory);
void send_transaction(const code& ec, transaction_const_ptr transaction,
size_t height, size_t position, inventory_ptr inventory);
void send_transaction(const code& ec, transaction_const_ptr message,
size_t position, size_t height, inventory_ptr inventory);

bool handle_receive_get_data(const code& ec,
get_data_const_ptr message);
Expand All @@ -63,10 +63,12 @@ class BCN_API protocol_transaction_out
bool handle_transaction_pool(const code& ec,
transaction_const_ptr message);

// These are thread safe.
blockchain::safe_chain& chain_;
std::atomic<uint64_t> minimum_peer_fee_;
////std::atomic<bool> compact_to_peer_;
const bool relay_to_peer_;
const bool enable_witness_;
};

} // namespace node
Expand Down
23 changes: 20 additions & 3 deletions src/parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ parser::parser(const configuration& defaults)
parser::parser(config::settings context)
: configured(context)
{
using serve = message::version::service;

// A node doesn't use history, and history is expensive.
configured.database.index_start_height = max_uint32;

Expand All @@ -61,8 +63,8 @@ parser::parser(config::settings context)
// A node allows 1000 host names by default.
configured.network.host_pool_capacity = 1000;

// A node exposes full node (1) network services by default.
configured.network.services = message::version::service::node_network;
// Expose full node (1) and witness (8) network services by default.
configured.network.services = serve::node_network | serve::node_witness;
}

options_metadata parser::load_options()
Expand Down Expand Up @@ -195,7 +197,7 @@ options_metadata parser::load_settings()
(
"network.services",
value<uint64_t>(&configured.network.services),
"The services exposed by network connections, defaults to 1 (full node)."
"The services exposed by network connections, defaults to 9 (full node, witness)."
)
(
"network.invalid_services",
Expand Down Expand Up @@ -413,6 +415,21 @@ options_metadata parser::load_settings()
value<bool>(&configured.chain.bip113),
"Use median time past for locktime, defaults to true (soft fork)."
)
(
"fork.bip141",
value<bool>(&configured.chain.bip141),
"Segregated witness consensus layer, defaults to true (soft fork)."
)
(
"fork.bip143",
value<bool>(&configured.chain.bip143),
"Version 0 transaction digest, defaults to true (soft fork)."
)
(
"fork.bip147",
value<bool>(&configured.chain.bip147),
"Prevent dummy value malleability, defaults to true (soft fork)."
)

/* [node] */
////(
Expand Down
30 changes: 30 additions & 0 deletions src/protocols/protocol_block_in.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@ using namespace bc::network;
using namespace std::chrono;
using namespace std::placeholders;

inline bool is_witness(uint64_t services)
{
return (services & version::service::node_witness) != 0;
}

protocol_block_in::protocol_block_in(full_node& node, channel::ptr channel,
safe_chain& chain)
: protocol_timer(node, channel, false, NAME),
Expand All @@ -58,6 +63,10 @@ protocol_block_in::protocol_block_in(full_node& node, channel::ptr channel,
blocks_from_peer_(
negotiated_version() > version::level::no_blocks_end ||
negotiated_version() < version::level::no_blocks_start),

// Witness must be requested if possibly enforced.
require_witness_(is_witness(node.network_settings().services)),
peer_witness_(is_witness(channel->peer_version()->services())),
CONSTRUCT_TRACK(protocol_block_in)
{
}
Expand All @@ -70,6 +79,11 @@ void protocol_block_in::start()
// Use timer to drop slow peers.
protocol_timer::start(block_latency_, BIND1(handle_timeout, _1));

// Do not process incoming blocks if required witness is unavailable.
// The channel will remain active outbound unless node becomes stale.
if (require_witness_ && !peer_witness_)
return;

// TODO: move headers to a derived class protocol_block_in_31800.
SUBSCRIBE2(headers, handle_receive_headers, _1, _2);

Expand Down Expand Up @@ -225,6 +239,10 @@ void protocol_block_in::send_get_data(const code& ec, get_data_ptr message)
mutex.unlock();
///////////////////////////////////////////////////////////////////////////

// Convert requested message types to corresponding witness types.
if (require_witness_)
message->to_witness();

// There was no backlog so the timer must be started now.
if (fresh)
reset_timer();
Expand Down Expand Up @@ -312,6 +330,15 @@ bool protocol_block_in::handle_receive_block(const code& ec,
return false;
}

if (!require_witness_ && message->is_segregated())
{
LOG_DEBUG(LOG_NODE)
<< "Block [" << encode_hash(message->hash())
<< "] contains unrequested witness from [" << authority() << "]";
stop(error::channel_stopped);
return false;
}

message->validation.originator = nonce();
chain_.organize(message, BIND2(handle_store_block, _1, message));

Expand Down Expand Up @@ -432,6 +459,9 @@ void protocol_block_in::handle_timeout(const code& ec)
// an announcement. There is no sense pinging a broken peer, so we either
// drop the peer after a certain mount of time (above 10 minutes) or rely
// on other peers to keep us moving and periodically age out connections.
// Note that this allows a non-witness peer to hang on indefinately to our
// witness-requiring node until the node becomes stale. Allowing this then
// depends on requiring witness peers for explicitly outbound connections.
}

void protocol_block_in::handle_stop(const code&)
Expand Down
36 changes: 28 additions & 8 deletions src/protocols/protocol_block_out.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include <functional>
#include <memory>
#include <string>
#include <boost/range/adaptor/reversed.hpp>
#include <bitcoin/blockchain.hpp>
#include <bitcoin/network.hpp>
#include <bitcoin/node/define.hpp>
Expand All @@ -38,8 +39,14 @@ namespace node {
using namespace bc::blockchain;
using namespace bc::message;
using namespace bc::network;
using namespace boost::adaptors;
using namespace std::placeholders;

inline bool is_witness(uint64_t services)
{
return (services & version::service::node_witness) != 0;
}

protocol_block_out::protocol_block_out(full_node& node, channel::ptr channel,
safe_chain& chain)
: protocol_events(node, channel, NAME),
Expand All @@ -53,6 +60,8 @@ protocol_block_out::protocol_block_out(full_node& node, channel::ptr channel,
// TODO: move send_headers to a derived class protocol_block_out_70012.
headers_to_peer_(false),

// Witness requests must be allowed if advertising the service.
enable_witness_(is_witness(node.network_settings().services)),
CONSTRUCT_TRACK(protocol_block_out)
{
}
Expand Down Expand Up @@ -276,7 +285,6 @@ bool protocol_block_out::handle_receive_get_data(const code& ec,
//// return true;

// Create a copy because message is const because it is shared.
const auto& inventories = message->inventories();
const auto response = std::make_shared<inventory>();

// TODO: convert all compact_block elements to block unless block is,
Expand All @@ -285,9 +293,9 @@ bool protocol_block_out::handle_receive_get_data(const code& ec,
// Peer may request compact only after receipt of a send_compact message.

// Reverse copy the block elements of the const inventory.
for (auto it = inventories.rbegin(); it != inventories.rend(); ++it)
if (it->is_block_type())
response->inventories().push_back(*it);
for (const auto inventory: reverse(message->inventories()))
if (inventory.is_block_type())
response->inventories().push_back(inventory);

send_next_data(response);
return true;
Expand All @@ -303,9 +311,21 @@ void protocol_block_out::send_next_data(inventory_ptr inventory)

switch (entry.type())
{
case inventory::type_id::witness_block:
{
if (!enable_witness_)
{
stop(error::channel_stopped);
return;
}

chain_.fetch_block(entry.hash(), true,
BIND4(send_block, _1, _2, _3, inventory));
break;
}
case inventory::type_id::block:
{
chain_.fetch_block(entry.hash(),
chain_.fetch_block(entry.hash(), false,
BIND4(send_block, _1, _2, _3, inventory));
break;
}
Expand All @@ -329,7 +349,7 @@ void protocol_block_out::send_next_data(inventory_ptr inventory)
}

void protocol_block_out::send_block(const code& ec, block_const_ptr message,
uint64_t, inventory_ptr inventory)
size_t, inventory_ptr inventory)
{
if (stopped(ec))
return;
Expand Down Expand Up @@ -361,7 +381,7 @@ void protocol_block_out::send_block(const code& ec, block_const_ptr message,

// TODO: move merkle_block to derived class protocol_block_out_70001.
void protocol_block_out::send_merkle_block(const code& ec,
merkle_block_const_ptr message, uint64_t, inventory_ptr inventory)
merkle_block_const_ptr message, size_t, inventory_ptr inventory)
{
if (stopped(ec))
return;
Expand Down Expand Up @@ -393,7 +413,7 @@ void protocol_block_out::send_merkle_block(const code& ec,

// TODO: move merkle_block to derived class protocol_block_out_70014.
void protocol_block_out::send_compact_block(const code& ec,
compact_block_const_ptr message, uint64_t, inventory_ptr inventory)
compact_block_const_ptr message, size_t, inventory_ptr inventory)
{
if (stopped(ec))
return;
Expand Down
Loading