Skip to content

Commit f74eaef

Browse files
authored
Merge pull request #10 from meritlabs/feature/referral-message
Referral transaction support
2 parents 412c7a1 + a708324 commit f74eaef

29 files changed

+615
-92
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,4 +112,8 @@ contrib/devtools/split-debug.sh
112112

113113
# IDEs
114114
.idea/
115+
.project
116+
.cproject
117+
.settings
118+
.tags*
115119
.vscode

src/Makefile.am

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ if ENABLE_ZMQ
3737
LIBBITCOIN_ZMQ=libbitcoin_zmq.a
3838
endif
3939
if BUILD_BITCOIN_LIBS
40+
LIBBITCOINCRYPTO=libbitcoincrypto.la
41+
LIBBITCOINUTIL=libbitcoinutil.la
4042
LIBBITCOINCONSENSUS=libbitcoinconsensus.la
4143
endif
4244
if ENABLE_WALLET
@@ -58,7 +60,7 @@ EXTRA_LIBRARIES += \
5860
$(LIBBITCOIN_WALLET) \
5961
$(LIBBITCOIN_ZMQ)
6062

61-
lib_LTLIBRARIES = $(LIBBITCOINCONSENSUS)
63+
lib_LTLIBRARIES = $(LIBBITCOINCRYPTO) $(LIBBITCOINUTIL) $(LIBBITCOINCONSENSUS)
6264

6365
bin_PROGRAMS =
6466
noinst_PROGRAMS =
@@ -290,7 +292,6 @@ libbitcoin_consensus_a_SOURCES = \
290292
primitives/transaction.cpp \
291293
primitives/transaction.h \
292294
primitives/referral.cpp \
293-
primitives/referral.h \
294295
pubkey.cpp \
295296
pubkey.h \
296297
script/bitcoinconsensus.cpp \
@@ -306,7 +307,8 @@ libbitcoin_consensus_a_SOURCES = \
306307
uint256.h \
307308
utilstrencodings.cpp \
308309
utilstrencodings.h \
309-
version.h
310+
version.h \
311+
$(BITCOIN_CORE_H)
310312

311313
# common: shared between bitcoind, and bitcoin-qt and non-server tools
312314
libbitcoin_common_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
@@ -437,14 +439,28 @@ bitcoin_tx_LDADD += $(BOOST_LIBS) $(CRYPTO_LIBS)
437439
# bitcoinconsensus library #
438440
if BUILD_BITCOIN_LIBS
439441
include_HEADERS = script/bitcoinconsensus.h
440-
libbitcoinconsensus_la_SOURCES = $(crypto_libbitcoin_crypto_a_SOURCES) $(libbitcoin_consensus_a_SOURCES)
442+
443+
libbitcoincrypto_la_SOURCES = $(crypto_libbitcoin_crypto_a_SOURCES)
444+
libbitcoincrypto_la_LDFLAGS = $(AM_LDFLAGS) -no-undefined $(RELDFLAGS)
445+
libbitcoincrypto_la_LIBADD = $(LIBUNIVALUE) $(CRYPTO_LIBS) $(SSL_LIBS) $(BOOST_LIBS)
446+
libbitcoincrypto_la_CPPFLAGS = $(AM_CPPFLAGS) -I$(builddir)/obj $(UNIVALUE_CFLAGS) $(CRYPTO_CFLAGS) $(SSL_CFLAGS)
447+
libbitcoincrypto_la_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
448+
449+
450+
libbitcoinutil_la_SOURCES = $(libbitcoin_util_a_SOURCES)
451+
libbitcoinutil_la_LDFLAGS = $(AM_LDFLAGS) -no-undefined $(RELDFLAGS)
452+
libbitcoinutil_la_LIBADD = $(LIBBITCOINCRYPTO) $(LIBUNIVALUE) $(CRYPTO_LIBS) $(SSL_LIBS) $(BOOST_LIBS)
453+
libbitcoinutil_la_CPPFLAGS = $(AM_CPPFLAGS) -I$(builddir)/obj $(UNIVALUE_CFLAGS) $(CRYPTO_CFLAGS) $(SSL_CFLAGS)
454+
libbitcoinutil_la_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
455+
456+
libbitcoinconsensus_la_SOURCES = $(libbitcoin_consensus_a_SOURCES)
441457

442458
if GLIBC_BACK_COMPAT
443459
libbitcoinconsensus_la_SOURCES += compat/glibc_compat.cpp
444460
endif
445461

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

src/consensus/merkle.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -159,16 +159,16 @@ uint256 BlockMerkleRoot(const CBlock& block, bool* mutated)
159159
{
160160
std::vector<uint256> leaves;
161161

162-
auto aggregateSize = block.vtx.size() + block.vref.size();
162+
auto aggregateSize = block.vtx.size() + block.m_vRef.size();
163163
leaves.resize(aggregateSize);
164164

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

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

173173
return ComputeMerkleRoot(leaves, mutated);
174174
}

src/init.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,7 @@ void Shutdown()
201201
UnregisterNodeSignals(GetNodeSignals());
202202
if (fDumpMempoolLater && gArgs.GetArg("-persistmempool", DEFAULT_PERSIST_MEMPOOL)) {
203203
DumpMempool();
204+
DumpReferralMempool();
204205
}
205206

206207
if (fFeeEstimatesInitialized)
@@ -690,6 +691,7 @@ void ThreadImport(std::vector<fs::path> vImportFiles)
690691
} // End scope of CImportingNow
691692
if (gArgs.GetArg("-persistmempool", DEFAULT_PERSIST_MEMPOOL)) {
692693
LoadMempool();
694+
LoadReferralMempool();
693695
fDumpMempoolLater = !fRequestShutdown;
694696
}
695697
}

src/miner.cpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
// its ancestors.
4444

4545
uint64_t nLastBlockTx = 0;
46+
uint64_t nLastBlockRef = 0;
4647
uint64_t nLastBlockSize = 0;
4748
uint64_t nLastBlockWeight = 0;
4849

@@ -123,6 +124,7 @@ void BlockAssembler::resetBlock()
123124

124125
// These counters do not include coinbase tx
125126
nBlockTx = 0;
127+
nBlockRef = 0;
126128
nFees = 0;
127129
}
128130

@@ -171,10 +173,12 @@ std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& sc
171173
int nPackagesSelected = 0;
172174
int nDescendantsUpdated = 0;
173175
addPackageTxs(nPackagesSelected, nDescendantsUpdated);
176+
AddReferrals();
174177

175178
int64_t nTime1 = GetTimeMicros();
176179

177180
nLastBlockTx = nBlockTx;
181+
nLastBlockRef = nBlockRef;
178182
nLastBlockSize = nBlockSize;
179183
nLastBlockWeight = nBlockWeight;
180184

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

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

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

340+
void BlockAssembler::AddReferrals()
341+
{
342+
for(auto const &ref: mempoolReferral.mapRTx) {
343+
pblock->m_vRef.push_back(ref.second);
344+
++nBlockRef;
345+
}
346+
}
347+
336348
// This transaction selection algorithm orders the mempool based
337349
// on feerate of a transaction including all unconfirmed ancestors.
338350
// Since we don't remove transactions from the mempool as we select them

src/miner.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ class BlockAssembler
147147
uint64_t nBlockWeight;
148148
uint64_t nBlockSize;
149149
uint64_t nBlockTx;
150+
uint64_t nBlockRef;
150151
uint64_t nBlockSigOpsCost;
151152
CAmount nFees;
152153
CTxMemPool::setEntries inBlock;
@@ -183,6 +184,9 @@ class BlockAssembler
183184
* statistics from the package selection (for logging statistics). */
184185
void addPackageTxs(int &nPackagesSelected, int &nDescendantsUpdated);
185186

187+
// Add referrals to block from mempoolReferral
188+
void AddReferrals();
189+
186190
// helper functions for addPackageTxs()
187191
/** Remove confirmed (inBlock) entries from given set */
188192
void onlyUnconfirmed(CTxMemPool::setEntries& testSet);

src/net.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -659,6 +659,7 @@ class CNode
659659
// Set of transaction ids we still have to announce.
660660
// They are sorted by the mempool before relay, so the order is not important.
661661
std::set<uint256> setInventoryTxToSend;
662+
std::set<uint256> setInventoryReferralToSend;
662663
// List of block ids we still have announce.
663664
// There is no final sorting before sending, as they are always sent immediately
664665
// and in the order requested.
@@ -806,6 +807,8 @@ class CNode
806807
}
807808
} else if (inv.type == MSG_BLOCK) {
808809
vInventoryBlockToSend.push_back(inv.hash);
810+
} else if (inv.type == MSG_REFERRAL) {
811+
setInventoryReferralToSend.insert(inv.hash);
809812
}
810813
}
811814

src/net_processing.cpp

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -905,6 +905,8 @@ bool static AlreadyHave(const CInv& inv) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
905905
case MSG_BLOCK:
906906
case MSG_WITNESS_BLOCK:
907907
return mapBlockIndex.count(inv.hash);
908+
case MSG_REFERRAL:
909+
return false;
908910
}
909911
// Don't know what it is, just say we already got one
910912
return true;
@@ -1123,6 +1125,13 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam
11231125
if (!push) {
11241126
vNotFound.push_back(inv);
11251127
}
1128+
} else if (inv.type == MSG_REFERRAL) {
1129+
auto it = mempoolReferral.mapRTx.find(inv.hash);
1130+
int nSendFlags = 0;
1131+
1132+
if (it != mempoolReferral.mapRTx.end()) {
1133+
connman.PushMessage(pfrom, msgMaker.Make(nSendFlags, NetMsgType::REF, *it->second));
1134+
}
11261135
}
11271136

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

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

1788+
else if (strCommand == NetMsgType::REF) {
1789+
ReferralRef rtx;
1790+
vRecv >> rtx;
1791+
1792+
LogPrintf("Referral message received\n");
1793+
1794+
AcceptToReferralMemoryPool(mempoolReferral, rtx);
1795+
}
1796+
17801797

17811798
else if (strCommand == NetMsgType::TX)
17821799
{
@@ -2659,6 +2676,26 @@ static bool SendRejectsAndCheckIfBanned(CNode* pnode, CConnman& connman)
26592676
return false;
26602677
}
26612678

2679+
void SendInventoryReferralsRequest(CNode* pto, CConnman& connman, const CNetMsgMaker& msgMaker)
2680+
{
2681+
std::vector<CInv> vInv;
2682+
2683+
vInv.reserve(std::max<size_t>(pto->setInventoryReferralToSend.size(), INVENTORY_BROADCAST_MAX));
2684+
2685+
for (const uint256& hash: pto->setInventoryReferralToSend) {
2686+
vInv.push_back(CInv(MSG_REFERRAL, hash));
2687+
if (vInv.size() == MAX_INV_SZ) {
2688+
connman.PushMessage(pto, msgMaker.Make(NetMsgType::INV, vInv));
2689+
vInv.clear();
2690+
}
2691+
}
2692+
2693+
pto->setInventoryReferralToSend.clear();
2694+
2695+
if (!vInv.empty())
2696+
connman.PushMessage(pto, msgMaker.Make(NetMsgType::INV, vInv));
2697+
}
2698+
26622699
bool ProcessMessages(CNode* pfrom, CConnman& connman, const std::atomic<bool>& interruptMsgProc)
26632700
{
26642701
const CChainParams& chainparams = Params();
@@ -3072,6 +3109,9 @@ bool SendMessages(CNode* pto, CConnman& connman, const std::atomic<bool>& interr
30723109
}
30733110
pto->vInventoryBlockToSend.clear();
30743111

3112+
// Add referrals
3113+
SendInventoryReferralsRequest(pto, connman, msgMaker);
3114+
30753115
// Check whether periodic sends should happen
30763116
bool fSendTrickle = pto->fWhitelisted;
30773117
if (pto->nNextInvSend < nNow) {

src/primitives/block.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,20 @@ uint256 CBlockHeader::GetHash() const
1818
std::string CBlock::ToString() const
1919
{
2020
std::stringstream s;
21-
s << strprintf("CBlock(hash=%s, ver=0x%08x, hashPrevBlock=%s, hashMerkleRoot=%s, nTime=%u, nBits=%08x, nNonce=%u, vtx=%u)\n",
21+
s << strprintf("CBlock(hash=%s, ver=0x%08x, hashPrevBlock=%s, hashMerkleRoot=%s, nTime=%u, nBits=%08x, nNonce=%u, vtx=%u, ref=%u)\n",
2222
GetHash().ToString(),
2323
nVersion,
2424
hashPrevBlock.ToString(),
2525
hashMerkleRoot.ToString(),
2626
nTime, nBits, nNonce,
27-
vtx.size());
27+
vtx.size(),
28+
m_vRef.size());
29+
2830
for (const auto& tx : vtx) {
2931
s << " " << tx->ToString() << "\n";
3032
}
33+
for (const auto& ref : m_vRef) {
34+
s << " " << ref->ToString() << "\n";
35+
}
3136
return s.str();
3237
}

src/primitives/block.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ class CBlock : public CBlockHeader
7575
public:
7676
// network and disk
7777
std::vector<CTransactionRef> vtx;
78-
std::vector<CReferralRef> vref;
78+
std::vector<ReferralRef> m_vRef;
7979

8080
// memory only
8181
mutable bool fChecked;
@@ -97,12 +97,14 @@ class CBlock : public CBlockHeader
9797
inline void SerializationOp(Stream& s, Operation ser_action) {
9898
READWRITE(*(CBlockHeader*)this);
9999
READWRITE(vtx);
100+
READWRITE(m_vRef);
100101
}
101102

102103
void SetNull()
103104
{
104105
CBlockHeader::SetNull();
105106
vtx.clear();
107+
m_vRef.clear();
106108
fChecked = false;
107109
}
108110

0 commit comments

Comments
 (0)