Merge pull request #254 from kleetus/bug/tx_events_mempool

Tx event firing
This commit is contained in:
Braydon Fuller 2015-09-23 15:57:10 -04:00
commit a624b6fa39
3 changed files with 60 additions and 147 deletions

View File

@ -10,6 +10,7 @@ before_install:
script:
- _mocha -R spec integration/regtest.js
- _mocha -R spec integration/regtest-node.js
- _mocha -R spec integration/p2p.js
- _mocha -R spec --recursive
cache:
directories:

View File

@ -381,6 +381,18 @@ index c65e842..0e44bb5 100644
CLevelDBWrapper(const boost::filesystem::path& path, size_t nCacheSize, bool fMemory = false, bool fWipe = false);
~CLevelDBWrapper();
diff --git a/src/main.cpp b/src/main.cpp
index 8f82abf..42bea1c 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1058,6 +1058,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
// Store transaction in memory
pool.addUnchecked(hash, entry, !IsInitialBlockDownload());
+ GetNodeSignals().TxToMemPool(tx);
}
SyncWithWallets(tx, NULL);
diff --git a/src/net.cpp b/src/net.cpp
index 3908be6..cf3ffd4 100644
--- a/src/net.cpp
@ -395,3 +407,17 @@ index 3908be6..cf3ffd4 100644
- nLocalHostNonce, FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, std::vector<string>()), nBestHeight, true);
+ nLocalHostNonce, FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, bitcore_node), nBestHeight, true);
}
diff --git a/src/net.h b/src/net.h
index 17502b9..e181d68 100644
--- a/src/net.h
+++ b/src/net.h
@@ -99,6 +99,7 @@ struct CNodeSignals
{
boost::signals2::signal<int ()> GetHeight;
boost::signals2::signal<bool (CNode*), CombinerAll> ProcessMessages;
+ boost::signals2::signal<bool (const CTransaction&)> TxToMemPool;
boost::signals2::signal<bool (CNode*, bool), CombinerAll> SendMessages;
boost::signals2::signal<void (NodeId, const CNode*)> InitializeNode;
boost::signals2::signal<void (NodeId)> FinalizeNode;

View File

@ -81,10 +81,7 @@ static void
async_get_tx_and_info_after(uv_work_t *req);
static bool
scan_messages(CNode* pfrom);
static bool
scan_messages_after(CNode* pfrom);
queueTx(const CTransaction&);
extern "C" void
init(Handle<Object>);
@ -93,7 +90,7 @@ init(Handle<Object>);
* Private Global Variables
* Used only by bitcoind functions.
*/
static std::vector<CDataStream> txmon_messages;
static std::vector<CTransaction> txQueue;
static uv_async_t txmon_async;
static Eternal<Function> txmon_callback;
static bool txmon_callback_available;
@ -278,8 +275,7 @@ NAN_METHOD(StartTxMon) {
txmon_callback_available = true;
CNodeSignals& nodeSignals = GetNodeSignals();
nodeSignals.ProcessMessages.connect(&scan_messages, boost::signals2::at_front);
nodeSignals.ProcessMessages.connect(&scan_messages_after, boost::signals2::at_back);
nodeSignals.TxToMemPool.connect(&queueTx);
uv_async_init(uv_default_loop(), &txmon_async, tx_notifier);
@ -291,37 +287,24 @@ tx_notifier(uv_async_t *handle) {
Isolate* isolate = Isolate::GetCurrent();
HandleScope scope(isolate);
{
LOCK(cs_main);
Local<Array> results = Array::New(isolate);
int arrayIndex = 0;
BOOST_FOREACH(CDataStream& vRecvCopy, txmon_messages) {
LOCK(cs_main);
BOOST_FOREACH(const CTransaction& tx, txQueue) {
std::string vRecvStr = vRecvCopy.str();
CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION);
ssTx << tx;
std::string stx = ssTx.str();
Local<Value> txBuffer = node::Buffer::New(isolate, stx.c_str(), stx.size());
Local<Value> txBuffer = node::Buffer::New(isolate, vRecvStr.c_str(), vRecvStr.size());
CTransaction tx;
vRecvCopy >> tx;
uint256 hash = tx.GetHash();
Local<Object> obj = NanNew<Object>();
bool existsInMempool = false;
CTransaction mtx;
if (mempool.lookup(hash, mtx))
{
existsInMempool = true;
}
obj->Set(NanNew<String>("buffer"), txBuffer);
obj->Set(NanNew<String>("hash"), NanNew<String>(hash.GetHex()));
obj->Set(NanNew<String>("mempool"), NanNew<Boolean>(existsInMempool));
obj->Set(NanNew<String>("mempool"), NanNew<Boolean>(true));
results->Set(arrayIndex, obj);
arrayIndex++;
@ -336,86 +319,15 @@ tx_notifier(uv_async_t *handle) {
cb->Call(isolate->GetCurrentContext()->Global(), argc, argv);
txmon_messages.clear();
txQueue.clear();
}
}
static bool
scan_messages_after(CNode* pfrom) {
if(txmon_messages.size() > 0) {
uv_async_send(&txmon_async);
}
return true;
}
static bool
scan_messages(CNode* pfrom) {
bool fOk = true;
std::deque<CNetMessage>::iterator it = pfrom->vRecvMsg.begin();
while (!pfrom->fDisconnect && it != pfrom->vRecvMsg.end()) {
// Don't bother if send buffer is too full to respond anyway
if (pfrom->nSendSize >= SendBufferSize()) {
break;
}
// get next message
CNetMessage& msg = *it;
// end, if an incomplete message is found
if (!msg.complete()) {
break;
}
// at this point, any failure means we can delete the current message
it++;
// Scan for message start
if (memcmp(msg.hdr.pchMessageStart, Params().MessageStart(), MESSAGE_START_SIZE) != 0) {
fOk = false;
break;
}
// Read header
CMessageHeader& hdr = msg.hdr;
if (!hdr.IsValid(Params().MessageStart())) {
continue;
}
std::string strCommand = hdr.GetCommand();
if (strCommand == (std::string)"tx") {
// Message size
unsigned int nMessageSize = hdr.nMessageSize;
// Checksum
CDataStream& vRecv = msg.vRecv;
uint256 hash = Hash(vRecv.begin(), vRecv.begin() + nMessageSize);
unsigned int nChecksum = 0;
memcpy(&nChecksum, &hash, sizeof(nChecksum));
if (nChecksum != hdr.nChecksum) {
continue;
}
// Copy the stream so that it can later be processed into the mempool
CDataStream vRecvCopy(vRecv.begin(), vRecv.end(), vRecv.GetType(), vRecv.GetVersion());
{
queueTx(const CTransaction& tx) {
LOCK(cs_main);
txmon_messages.push_back(vRecvCopy);
}
}
boost::this_thread::interruption_point();
break;
}
return fOk;
txQueue.push_back(tx);
uv_async_send(&txmon_async);
return true;
}
/**
@ -1556,32 +1468,6 @@ NAN_METHOD(SendTransaction) {
// Relay the transaction connect peers
RelayTransaction(tx);
// Notify any listeners about the transaction
if(txmon_callback_available) {
Local<Array> results = Array::New(isolate);
Local<Object> obj = NanNew<Object>();
CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION);
ssTx << tx;
std::string stx = ssTx.str();
Local<Value> txBuffer = node::Buffer::New(isolate, stx.c_str(), stx.size());
obj->Set(NanNew<String>("buffer"), txBuffer);
obj->Set(NanNew<String>("hash"), NanNew<String>(hashTx.GetHex()));
obj->Set(NanNew<String>("mempool"), NanNew<Boolean>(true));
results->Set(0, obj);
const unsigned argc = 1;
Local<Value> argv[argc] = {
Local<Value>::New(isolate, results)
};
Local<Function> cb = txmon_callback.Get(isolate);
cb->Call(isolate->GetCurrentContext()->Global(), argc, argv);
}
NanReturnValue(Local<Value>::New(isolate, NanNew<String>(hashTx.GetHex())));
}