Skip to content

Commit

Permalink
Merge pull request #10 from meritlabs/feature/referral-message
Browse files Browse the repository at this point in the history
Referral transaction support
  • Loading branch information
mempko authored Aug 28, 2017
2 parents e47d382 + 9e2a314 commit d3f6ca7
Show file tree
Hide file tree
Showing 29 changed files with 615 additions and 92 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -112,4 +112,8 @@ contrib/devtools/split-debug.sh

# IDEs
.idea/
.project
.cproject
.settings
.tags*
.vscode
26 changes: 21 additions & 5 deletions src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ if ENABLE_ZMQ
LIBBITCOIN_ZMQ=libbitcoin_zmq.a
endif
if BUILD_BITCOIN_LIBS
LIBBITCOINCRYPTO=libbitcoincrypto.la
LIBBITCOINUTIL=libbitcoinutil.la
LIBBITCOINCONSENSUS=libbitcoinconsensus.la
endif
if ENABLE_WALLET
Expand All @@ -58,7 +60,7 @@ EXTRA_LIBRARIES += \
$(LIBBITCOIN_WALLET) \
$(LIBBITCOIN_ZMQ)

lib_LTLIBRARIES = $(LIBBITCOINCONSENSUS)
lib_LTLIBRARIES = $(LIBBITCOINCRYPTO) $(LIBBITCOINUTIL) $(LIBBITCOINCONSENSUS)

bin_PROGRAMS =
noinst_PROGRAMS =
Expand Down Expand Up @@ -290,7 +292,6 @@ libbitcoin_consensus_a_SOURCES = \
primitives/transaction.cpp \
primitives/transaction.h \
primitives/referral.cpp \
primitives/referral.h \
pubkey.cpp \
pubkey.h \
script/bitcoinconsensus.cpp \
Expand All @@ -306,7 +307,8 @@ libbitcoin_consensus_a_SOURCES = \
uint256.h \
utilstrencodings.cpp \
utilstrencodings.h \
version.h
version.h \
$(BITCOIN_CORE_H)

# common: shared between bitcoind, and bitcoin-qt and non-server tools
libbitcoin_common_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
Expand Down Expand Up @@ -437,14 +439,28 @@ bitcoin_tx_LDADD += $(BOOST_LIBS) $(CRYPTO_LIBS)
# bitcoinconsensus library #
if BUILD_BITCOIN_LIBS
include_HEADERS = script/bitcoinconsensus.h
libbitcoinconsensus_la_SOURCES = $(crypto_libbitcoin_crypto_a_SOURCES) $(libbitcoin_consensus_a_SOURCES)

libbitcoincrypto_la_SOURCES = $(crypto_libbitcoin_crypto_a_SOURCES)
libbitcoincrypto_la_LDFLAGS = $(AM_LDFLAGS) -no-undefined $(RELDFLAGS)
libbitcoincrypto_la_LIBADD = $(LIBUNIVALUE) $(CRYPTO_LIBS) $(SSL_LIBS) $(BOOST_LIBS)
libbitcoincrypto_la_CPPFLAGS = $(AM_CPPFLAGS) -I$(builddir)/obj $(UNIVALUE_CFLAGS) $(CRYPTO_CFLAGS) $(SSL_CFLAGS)
libbitcoincrypto_la_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)


libbitcoinutil_la_SOURCES = $(libbitcoin_util_a_SOURCES)
libbitcoinutil_la_LDFLAGS = $(AM_LDFLAGS) -no-undefined $(RELDFLAGS)
libbitcoinutil_la_LIBADD = $(LIBBITCOINCRYPTO) $(LIBUNIVALUE) $(CRYPTO_LIBS) $(SSL_LIBS) $(BOOST_LIBS)
libbitcoinutil_la_CPPFLAGS = $(AM_CPPFLAGS) -I$(builddir)/obj $(UNIVALUE_CFLAGS) $(CRYPTO_CFLAGS) $(SSL_CFLAGS)
libbitcoinutil_la_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)

libbitcoinconsensus_la_SOURCES = $(libbitcoin_consensus_a_SOURCES)

if GLIBC_BACK_COMPAT
libbitcoinconsensus_la_SOURCES += compat/glibc_compat.cpp
endif

libbitcoinconsensus_la_LDFLAGS = $(AM_LDFLAGS) -no-undefined $(RELDFLAGS)
libbitcoinconsensus_la_LIBADD = $(LIBBITCOIN_UTIL) $(LIBSECP256K1) $(SSL_LIBS) $(CRYPTO_LIBS) $(BOOST_LIBS)
libbitcoinconsensus_la_LIBADD = $(LIBSECP256K1) $(LIBBITCOINCRYPTO) $(LIBBITCOINUTIL) $(BOOST_LIBS)
libbitcoinconsensus_la_CPPFLAGS = $(AM_CPPFLAGS) -I$(builddir)/obj -I$(srcdir)/secp256k1/include -DBUILD_BITCOIN_INTERNAL
libbitcoinconsensus_la_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)

Expand Down
8 changes: 4 additions & 4 deletions src/consensus/merkle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,16 +159,16 @@ uint256 BlockMerkleRoot(const CBlock& block, bool* mutated)
{
std::vector<uint256> leaves;

auto aggregateSize = block.vtx.size() + block.vref.size();
auto aggregateSize = block.vtx.size() + block.m_vRef.size();
leaves.resize(aggregateSize);

for (size_t s = 0; s < block.vtx.size(); s++) {
leaves[s] = block.vtx[s]->GetHash();
}

for (size_t s = block.vtx.size(); s < aggregateSize; s++) {
leaves[s] = block.vref[s]->GetHash();
}
for (size_t s = 0; s < block.m_vRef.size(); s++) {
leaves[block.vtx.size() + s] = block.m_vRef[s]->GetHash();
};

return ComputeMerkleRoot(leaves, mutated);
}
Expand Down
2 changes: 2 additions & 0 deletions src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,7 @@ void Shutdown()
UnregisterNodeSignals(GetNodeSignals());
if (fDumpMempoolLater && gArgs.GetArg("-persistmempool", DEFAULT_PERSIST_MEMPOOL)) {
DumpMempool();
DumpReferralMempool();
}

if (fFeeEstimatesInitialized)
Expand Down Expand Up @@ -690,6 +691,7 @@ void ThreadImport(std::vector<fs::path> vImportFiles)
} // End scope of CImportingNow
if (gArgs.GetArg("-persistmempool", DEFAULT_PERSIST_MEMPOOL)) {
LoadMempool();
LoadReferralMempool();
fDumpMempoolLater = !fRequestShutdown;
}
}
Expand Down
14 changes: 13 additions & 1 deletion src/miner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
// its ancestors.

uint64_t nLastBlockTx = 0;
uint64_t nLastBlockRef = 0;
uint64_t nLastBlockSize = 0;
uint64_t nLastBlockWeight = 0;

Expand Down Expand Up @@ -123,6 +124,7 @@ void BlockAssembler::resetBlock()

// These counters do not include coinbase tx
nBlockTx = 0;
nBlockRef = 0;
nFees = 0;
}

Expand Down Expand Up @@ -171,10 +173,12 @@ std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& sc
int nPackagesSelected = 0;
int nDescendantsUpdated = 0;
addPackageTxs(nPackagesSelected, nDescendantsUpdated);
AddReferrals();

int64_t nTime1 = GetTimeMicros();

nLastBlockTx = nBlockTx;
nLastBlockRef = nBlockRef;
nLastBlockSize = nBlockSize;
nLastBlockWeight = nBlockWeight;

Expand All @@ -191,7 +195,7 @@ std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& sc
pblocktemplate->vTxFees[0] = -nFees;

uint64_t nSerializeSize = GetSerializeSize(*pblock, SER_NETWORK, PROTOCOL_VERSION);
LogPrintf("CreateNewBlock(): total size: %u block weight: %u txs: %u fees: %ld sigops %d\n", nSerializeSize, GetBlockWeight(*pblock), nBlockTx, nFees, nBlockSigOpsCost);
LogPrintf("CreateNewBlock(): total size: %u block weight: %u txs: %u fees: %ld sigops: %d refs: %d\n", nSerializeSize, GetBlockWeight(*pblock), nBlockTx, nFees, nBlockSigOpsCost, nBlockRef);

// Fill in header
pblock->hashPrevBlock = pindexPrev->GetBlockHash();
Expand Down Expand Up @@ -333,6 +337,14 @@ void BlockAssembler::SortForBlock(const CTxMemPool::setEntries& package, CTxMemP
std::sort(sortedEntries.begin(), sortedEntries.end(), CompareTxIterByAncestorCount());
}

void BlockAssembler::AddReferrals()
{
for(auto const &ref: mempoolReferral.mapRTx) {
pblock->m_vRef.push_back(ref.second);
++nBlockRef;
}
}

// This transaction selection algorithm orders the mempool based
// on feerate of a transaction including all unconfirmed ancestors.
// Since we don't remove transactions from the mempool as we select them
Expand Down
4 changes: 4 additions & 0 deletions src/miner.h
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ class BlockAssembler
uint64_t nBlockWeight;
uint64_t nBlockSize;
uint64_t nBlockTx;
uint64_t nBlockRef;
uint64_t nBlockSigOpsCost;
CAmount nFees;
CTxMemPool::setEntries inBlock;
Expand Down Expand Up @@ -183,6 +184,9 @@ class BlockAssembler
* statistics from the package selection (for logging statistics). */
void addPackageTxs(int &nPackagesSelected, int &nDescendantsUpdated);

// Add referrals to block from mempoolReferral
void AddReferrals();

// helper functions for addPackageTxs()
/** Remove confirmed (inBlock) entries from given set */
void onlyUnconfirmed(CTxMemPool::setEntries& testSet);
Expand Down
3 changes: 3 additions & 0 deletions src/net.h
Original file line number Diff line number Diff line change
Expand Up @@ -659,6 +659,7 @@ class CNode
// Set of transaction ids we still have to announce.
// They are sorted by the mempool before relay, so the order is not important.
std::set<uint256> setInventoryTxToSend;
std::set<uint256> setInventoryReferralToSend;
// List of block ids we still have announce.
// There is no final sorting before sending, as they are always sent immediately
// and in the order requested.
Expand Down Expand Up @@ -806,6 +807,8 @@ class CNode
}
} else if (inv.type == MSG_BLOCK) {
vInventoryBlockToSend.push_back(inv.hash);
} else if (inv.type == MSG_REFERRAL) {
setInventoryReferralToSend.insert(inv.hash);
}
}

Expand Down
42 changes: 41 additions & 1 deletion src/net_processing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -905,6 +905,8 @@ bool static AlreadyHave(const CInv& inv) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
case MSG_BLOCK:
case MSG_WITNESS_BLOCK:
return mapBlockIndex.count(inv.hash);
case MSG_REFERRAL:
return false;
}
// Don't know what it is, just say we already got one
return true;
Expand Down Expand Up @@ -1123,6 +1125,13 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam
if (!push) {
vNotFound.push_back(inv);
}
} else if (inv.type == MSG_REFERRAL) {
auto it = mempoolReferral.mapRTx.find(inv.hash);
int nSendFlags = 0;

if (it != mempoolReferral.mapRTx.end()) {
connman.PushMessage(pfrom, msgMaker.Make(nSendFlags, NetMsgType::REF, *it->second));
}
}

// Track requests for our stuff.
Expand Down Expand Up @@ -1526,7 +1535,6 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
}
}


else if (strCommand == NetMsgType::INV)
{
std::vector<CInv> vInv;
Expand Down Expand Up @@ -1777,6 +1785,15 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
connman.PushMessage(pfrom, msgMaker.Make(NetMsgType::HEADERS, vHeaders));
}

else if (strCommand == NetMsgType::REF) {
ReferralRef rtx;
vRecv >> rtx;

LogPrintf("Referral message received\n");

AcceptToReferralMemoryPool(mempoolReferral, rtx);
}


else if (strCommand == NetMsgType::TX)
{
Expand Down Expand Up @@ -2659,6 +2676,26 @@ static bool SendRejectsAndCheckIfBanned(CNode* pnode, CConnman& connman)
return false;
}

void SendInventoryReferralsRequest(CNode* pto, CConnman& connman, const CNetMsgMaker& msgMaker)
{
std::vector<CInv> vInv;

vInv.reserve(std::max<size_t>(pto->setInventoryReferralToSend.size(), INVENTORY_BROADCAST_MAX));

for (const uint256& hash: pto->setInventoryReferralToSend) {
vInv.push_back(CInv(MSG_REFERRAL, hash));
if (vInv.size() == MAX_INV_SZ) {
connman.PushMessage(pto, msgMaker.Make(NetMsgType::INV, vInv));
vInv.clear();
}
}

pto->setInventoryReferralToSend.clear();

if (!vInv.empty())
connman.PushMessage(pto, msgMaker.Make(NetMsgType::INV, vInv));
}

bool ProcessMessages(CNode* pfrom, CConnman& connman, const std::atomic<bool>& interruptMsgProc)
{
const CChainParams& chainparams = Params();
Expand Down Expand Up @@ -3072,6 +3109,9 @@ bool SendMessages(CNode* pto, CConnman& connman, const std::atomic<bool>& interr
}
pto->vInventoryBlockToSend.clear();

// Add referrals
SendInventoryReferralsRequest(pto, connman, msgMaker);

// Check whether periodic sends should happen
bool fSendTrickle = pto->fWhitelisted;
if (pto->nNextInvSend < nNow) {
Expand Down
9 changes: 7 additions & 2 deletions src/primitives/block.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,20 @@ uint256 CBlockHeader::GetHash() const
std::string CBlock::ToString() const
{
std::stringstream s;
s << strprintf("CBlock(hash=%s, ver=0x%08x, hashPrevBlock=%s, hashMerkleRoot=%s, nTime=%u, nBits=%08x, nNonce=%u, vtx=%u)\n",
s << strprintf("CBlock(hash=%s, ver=0x%08x, hashPrevBlock=%s, hashMerkleRoot=%s, nTime=%u, nBits=%08x, nNonce=%u, vtx=%u, ref=%u)\n",
GetHash().ToString(),
nVersion,
hashPrevBlock.ToString(),
hashMerkleRoot.ToString(),
nTime, nBits, nNonce,
vtx.size());
vtx.size(),
m_vRef.size());

for (const auto& tx : vtx) {
s << " " << tx->ToString() << "\n";
}
for (const auto& ref : m_vRef) {
s << " " << ref->ToString() << "\n";
}
return s.str();
}
4 changes: 3 additions & 1 deletion src/primitives/block.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ class CBlock : public CBlockHeader
public:
// network and disk
std::vector<CTransactionRef> vtx;
std::vector<CReferralRef> vref;
std::vector<ReferralRef> m_vRef;

// memory only
mutable bool fChecked;
Expand All @@ -97,12 +97,14 @@ class CBlock : public CBlockHeader
inline void SerializationOp(Stream& s, Operation ser_action) {
READWRITE(*(CBlockHeader*)this);
READWRITE(vtx);
READWRITE(m_vRef);
}

void SetNull()
{
CBlockHeader::SetNull();
vtx.clear();
m_vRef.clear();
fChecked = false;
}

Expand Down
Loading

0 comments on commit d3f6ca7

Please sign in to comment.