Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
c4d3a12
[BlockSigner] Add block signer thread initialization code.
maaku Jul 13, 2021
cdae6ed
[BlockSigner] Add utility function for fetching wallet to use for blo…
maaku Aug 10, 2021
a93c459
[BlockSigner] Parse federation and block signer configuration options.
maaku Aug 9, 2021
daf40f3
[BlockSigner] Use the wallet to generate blocks at fixed intervals.
maaku Aug 3, 2021
bf079d1
[BlockSigner] Add 'blocksign' p2p message, and handshake protocol.
maaku Aug 10, 2021
0107ee1
[BlockSigner] Add peer-to-peer protocol for sharing block proposals, …
maaku Aug 10, 2021
826ca7f
[BlockSigner] Add script demonstrating how to use the federated block…
maaku Aug 11, 2021
79a9dcd
f '[BlockSigner] Parse federation and block signer configuration opti…
maaku Aug 21, 2021
b3a0ab9
f '[BlockSigner] Parse federation and block signer configuration opti…
maaku Aug 21, 2021
1da1bbb
f '[BlockSigner] Parse federation and block signer configuration opti…
maaku Aug 21, 2021
bf28ee6
f '[BlockSigner] Add script demonstrating how to use the federated bl…
maaku Aug 21, 2021
2817b6a
f '[BlockSigner] Parse federation and block signer configuration opti…
maaku Aug 21, 2021
fef2e4e
f '[BlockSigner] Parse federation and block signer configuration opti…
maaku Aug 21, 2021
2722026
f '[BlockSigner] Use the wallet to generate blocks at fixed intervals.'
maaku Aug 21, 2021
c4500a8
f '[BlockSigner] Use the wallet to generate blocks at fixed intervals.'
maaku Aug 21, 2021
910b875
f '[BlockSigner] Use the wallet to generate blocks at fixed intervals.'
maaku Aug 21, 2021
0c5d845
f '[BlockSigner] Add 'blocksign' p2p message, and handshake protocol.'
maaku Aug 21, 2021
6bb86db
f '[BlockSigner] Add 'blocksign' p2p message, and handshake protocol.'
maaku Aug 21, 2021
cb96642
f '[BlockSigner] Add peer-to-peer protocol for sharing block proposal…
maaku Aug 21, 2021
45a9dbd
f '[BlockSigner] Add 'blocksign' p2p message, and handshake protocol.'
maaku Aug 21, 2021
8efa38a
f '[BlockSigner] Add peer-to-peer protocol for sharing block proposal…
maaku Aug 21, 2021
8862190
f '[BlockSigner] Parse federation and block signer configuration opti…
maaku Aug 21, 2021
3c70538
[Mining] Explicitly record block height as part of CBlockTemplate str…
maaku Nov 16, 2021
cbae6d7
f '[BlockSigner] Use the wallet to generate blocks at fixed intervals.'
maaku Nov 16, 2021
9c375ba
[BlockSigner] Verify and store ACK signature from block proposal.
maaku Dec 6, 2021
ba4cc36
[ElementsRegtest] Add public parameters for block-signer elementsregt…
maaku Dec 6, 2021
8cc00bc
f '[ElementsRegtest] Add public parameters for block-signer elementsr…
maaku Dec 7, 2021
8a98f08
[BlockSigner] Ignore empty block proposals, exept every 15 minutes.
maaku Dec 7, 2021
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
114 changes: 114 additions & 0 deletions src/federation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <miner.h>
#include <netaddress.h>
#include <netbase.h>
#include <netmessagemaker.h>
#include <net.h>
#include <node/context.h>
#include <pow.h>
Expand Down Expand Up @@ -237,12 +238,57 @@ static bool ReadFederationOpts() {
return !errors;
}

//! A record of which nodes have identified themselves as block-signing peers,
//! and their associated public keys.
static std::map<NodeId, CPubKey> g_fednode_conn;

//! The current block proposal, which is announced by the leader at the
//! beginning of their round.
static CBlock g_block_proposal;
//! A collection of valid signatures for the proposed block of the current round.
static std::map<CPubKey, std::vector<unsigned char>> g_block_sigs;

// Our peer-to-peer messages all transmitted as NetMsgType::BLOCKSIGN messages
// on the wire. We differentiate the type of message for our own purposes with
// a sub-message command, a single byte value at the beginning of the message
// payload.
namespace BlockSignMsgType {
const unsigned char VER = 0;
const unsigned char VERACK = 1;
} // namespace BlockSignMsgType

// Checks if the specified peer is in the whitelist, and if so sends it a VER
// message.
static void HandshakePeer(CNode* pnode) {
LOCK(cs_block_signer);

if (g_fednode_conn.count(pnode->GetId())) {
// Already handshaked
return;
}

bool match = false;
for (const auto& subnet : g_whitelist) {
if (subnet.Match(pnode->addr)) {
match = true;
break;
}
}

if (match) {
g_context->connman->PushMessage(pnode, CNetMsgMaker(pnode->GetCommonVersion()).Make(
NetMsgType::BLOCKSIGN,
BlockSignMsgType::VER,
g_our_block_signing_key));
}
}

// Checks if the connection manager has connected to any new nodes since we were
// last called, and attempts a handshake if these nodes are in the whitelist.
static void HandshakeNewConnections() {
g_context->connman->ForEachNode(HandshakePeer);
}

static bool GenerateBlockProposal()
{
const CChainParams& params = Params();
Expand Down Expand Up @@ -411,6 +457,11 @@ void ThreadBlockSigner(NodeContext& node)
// Make node context accessible everywhere from within this file.
g_context = &node;

if (!g_context->connman) {
LogPrint(BCLog::FEDERATION, "Error: peer-to-peer functionality missing or disabled. Unable to start block signer.\n");
return;
}

// Parse the various federation and block signing configuration
// options and initialize the global variable state accordingly.
if (!ReadFederationOpts()) {
Expand All @@ -428,6 +479,8 @@ void ThreadBlockSigner(NodeContext& node)
std::chrono::steady_clock::now().time_since_epoch()));

while (true) {
HandshakeNewConnections();

// Sleep this thread until the start of the next block interval.
nextblocktime += std::chrono::minutes{1};
if (!g_thread_interrupt.sleep_until(nextblocktime)) {
Expand Down Expand Up @@ -467,4 +520,65 @@ void ThreadBlockSigner(NodeContext& node)
}
}

void HandleBlockSignMessage(CNode& from, CDataStream& msg, std::chrono::microseconds time_received, const std::atomic<bool>& interrupt_msg_proc)
{
unsigned char code;
msg >> code;

switch (code) {
case BlockSignMsgType::VER:
case BlockSignMsgType::VERACK:
{
LOCK(cs_block_signer);

CPubKey other;
msg >> other;
if (!other.IsFullyValid()) {
LogPrint(BCLog::FEDERATION, "Received blocksign::VER%s message with invalid/malformed public key. Ignoring.\n", (code == BlockSignMsgType::VERACK) ? "ACK" : "");
Comment thread
maaku marked this conversation as resolved.
Outdated
break;
}
if (std::find(g_block_signing_keys.begin(), g_block_signing_keys.end(), other) == g_block_signing_keys.end()) {
std::string pkstr(HexStr(CDataStream(SER_NETWORK, CLIENT_VERSION) << other), 2);
LogPrint(BCLog::FEDERATION, "Received blocksign::VER%s message with unrecognized public key %s. Ignoring.\n", (code == BlockSignMsgType::VERACK) ? "ACK" : "", pkstr);
break;
}
if (!g_block_signers.count(other)) {
std::string pkstr(HexStr(CDataStream(SER_NETWORK, CLIENT_VERSION) << other), 2);
LogPrint(BCLog::FEDERATION, "Received blocksign::VER%s message with known public key, but cannot find record for peer: %s. Ignoring. Are you missing a a '-blocksignnode=%s:<ip:port>' configuration parameter?\n", (code == BlockSignMsgType::VERACK) ? "ACK" : "", pkstr, pkstr);
Comment thread
maaku marked this conversation as resolved.
Outdated
break;
}

g_fednode_conn[from.GetId()] = other;
g_block_signers[other].m_nodes.insert(from.GetId());

if (code == BlockSignMsgType::VERACK) {
break;
}

// FIXME: Don't duplicate HandshakePeer
Comment thread
kallewoof marked this conversation as resolved.
Outdated
bool match = false;
for (const auto& subnet : g_whitelist) {
if (subnet.Match(from.addr)) {
match = true;
break;
}
}

if (!match) {
break;
}

g_context->connman->PushMessage(&from, CNetMsgMaker(from.GetCommonVersion()).Make(
NetMsgType::BLOCKSIGN,
BlockSignMsgType::VERACK,
g_our_block_signing_key));
}
break;

default:
LogPrint(BCLog::FEDERATION, "Received an unrecognized blocksign message (code=%d) from peer=%d. Ignoring.\n", code, from.GetId());
break;
}
}

// End of File
10 changes: 10 additions & 0 deletions src/federation.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,13 @@
#ifndef BITCOIN_FEDERATION_H
#define BITCOIN_FEDERATION_H

#include <net.h>
#include <node/context.h>
#include <streams.h>

#include <atomic>
#include <chrono>
#include <cstdint>

/** Run an instance of the block-signing protocol manager. */
void ThreadBlockSigner(NodeContext &node);
Expand All @@ -15,6 +21,10 @@ void ThreadBlockSigner(NodeContext &node);
// routine. This should be investigated and removed if possible.
void InterruptBlockSignerThread();

/** Called by the code in net_processing.cpp, handles a BLOCKSIGN message from a
** federation peer. */
void HandleBlockSignMessage(CNode& from, CDataStream& msg, std::chrono::microseconds time_received, const std::atomic<bool>& interrupt_msg_proc);

#endif // BITCOIN_FEDERATION_H

// End of File
6 changes: 6 additions & 0 deletions src/net_processing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <blockfilter.h>
#include <chainparams.h>
#include <consensus/validation.h>
#include <federation.h>
#include <hash.h>
#include <index/blockfilterindex.h>
#include <merkleblock.h>
Expand Down Expand Up @@ -3750,6 +3751,11 @@ void PeerManager::ProcessMessage(CNode& pfrom, const std::string& msg_type, CDat
return;
}

if (msg_type == NetMsgType::BLOCKSIGN) {
HandleBlockSignMessage(pfrom, vRecv, time_received, interruptMsgProc);
return;
}

// Ignore unknown commands for extensibility
LogPrint(BCLog::NET, "Unknown command \"%s\" from peer=%d\n", SanitizeString(msg_type), pfrom.GetId());
return;
Expand Down
1 change: 1 addition & 0 deletions src/protocol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ const char *SENDCMPCT="sendcmpct";
const char *CMPCTBLOCK="cmpctblock";
const char *GETBLOCKTXN="getblocktxn";
const char *BLOCKTXN="blocktxn";
const char *BLOCKSIGN="blocksign";
const char *GETCFILTERS="getcfilters";
const char *CFILTER="cfilter";
const char *GETCFHEADERS="getcfheaders";
Expand Down
3 changes: 3 additions & 0 deletions src/protocol.h
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,9 @@ extern const char* GETBLOCKTXN;
* @since protocol version 70014 as described by BIP 152
*/
extern const char* BLOCKTXN;
/**
*/
extern const char *BLOCKSIGN;
/**
* getcfilters requests compact filters for a range of blocks.
* Only available with service bit NODE_COMPACT_FILTERS as described by
Expand Down