Completed getMempoolOutputs

- Pass ctx to data from the mempool for getTransaction
- Use string as input for unchecked transaction to mempool
- Only include outputs that match input address
- Include script in results
This commit is contained in:
Braydon Fuller 2015-07-17 21:24:59 -04:00
parent ef3abbcb6c
commit 0b926b67b6
3 changed files with 78 additions and 52 deletions

View File

@ -135,46 +135,55 @@ describe('Basic Functionality', function() {
}); });
}); });
describe('add to mempool', function() { describe('mempool functionality', function() {
it('will add an uncheckedTransaction', function() {
var fromAddress = 'mszYqVnqKoQx4jcTdJXxwKAissE3Jbrrc1'; var fromAddress = 'mszYqVnqKoQx4jcTdJXxwKAissE3Jbrrc1';
var utxo = { var utxo = {
address: fromAddress, address: fromAddress,
txId: 'a477af6b2667c29670467e4e0728b685ee07b240235771862318e29ddbe58458', txId: 'a477af6b2667c29670467e4e0728b685ee07b240235771862318e29ddbe58458',
outputIndex: 0, outputIndex: 0,
script: Script.buildPublicKeyHashOut(fromAddress).toString(), script: bitcore.Script.buildPublicKeyHashOut(fromAddress).toString(),
satoshis: 100000 satoshis: 100000
}; };
var toAddress = 'mrU9pEmAx26HcbKVrABvgL7AwA5fjNFoDc'; var toAddress = 'mrU9pEmAx26HcbKVrABvgL7AwA5fjNFoDc';
var changeAddress = 'mgBCJAsvzgT2qNNeXsoECg2uPKrUsZ76up'; var changeAddress = 'mgBCJAsvzgT2qNNeXsoECg2uPKrUsZ76up';
var changeAddressP2SH = '2N7T3TAetJrSCruQ39aNrJvYLhG1LJosujf'; var changeAddressP2SH = '2N7T3TAetJrSCruQ39aNrJvYLhG1LJosujf';
var privateKey = 'cSBnVM4xvxarwGQuAfQFwqDg9k5tErHUHzgWsEfD4zdwUasvqRVY'; var privateKey = 'cSBnVM4xvxarwGQuAfQFwqDg9k5tErHUHzgWsEfD4zdwUasvqRVY';
var private1 = '6ce7e97e317d2af16c33db0b9270ec047a91bff3eff8558afb5014afb2bb5976'; var private1 = '6ce7e97e317d2af16c33db0b9270ec047a91bff3eff8558afb5014afb2bb5976';
var private2 = 'c9b26b0f771a0d2dad88a44de90f05f416b3b385ff1d989343005546a0032890'; var private2 = 'c9b26b0f771a0d2dad88a44de90f05f416b3b385ff1d989343005546a0032890';
var tx = new bitcore.Transaction(); var tx = new bitcore.Transaction();
tx.from(utxo); tx.from(utxo);
tx.to(toAddress, 50000); tx.to(toAddress, 50000);
tx.change(changeAddress); tx.change(changeAddress);
tx.sign(privateKey); tx.sign(privateKey);
var added = bitcoind.addMempoolUncheckedTransaction(tx.toBuffer());
it('will add an unchecked transaction', function() {
var added = bitcoind.addMempoolUncheckedTransaction(tx.serialize());
added.should.equal(true); added.should.equal(true);
bitcoind.getTransaction(tx.hash, true, function(err, tx) { bitcoind.getTransaction(tx.hash, true, function(err, txBuffer) {
if(err) { if(err) {
throw err; throw err;
} }
tx.toString('hex').should.equal(tx.toBuffer().toString('hex')); var expected = tx.toBuffer().toString('hex');
txBuffer.toString('hex').should.equal(expected);
}); });
}); });
});
describe('get outputs by address from the mempool', function() { it('get outputs by address', function() {
it('will do it', function() { var outputs = bitcoind.getMempoolOutputs(changeAddress);
var outputs = bitcoind.getMempoolOutputs('n28S35tqEMbt6vNad7A5K3mZ7vdn8dZ86X'); var expected = [
Array.isArray(outputs).should.equal(true); {
script: 'OP_DUP OP_HASH160 073b7eae2823efa349e3b9155b8a735526463a0f OP_EQUALVERIFY OP_CHECKSIG',
satoshis: 40000,
txid: tx.hash,
outputIndex: 1
}
];
outputs.should.deep.equal(expected);
}); });
});
});
}); });

View File

@ -386,6 +386,10 @@ Bitcoin.prototype.getMempoolOutputs = function(address) {
return bitcoindjs.getMempoolOutputs(address); return bitcoindjs.getMempoolOutputs(address);
}; };
Bitcoin.prototype.addMempoolUncheckedTransaction = function(txBuffer) {
return bitcoindjs.addMempoolUncheckedTransaction(txBuffer);
};
Bitcoin.prototype.getInfo = function() { Bitcoin.prototype.getInfo = function() {
if (bitcoin.stopping) return []; if (bitcoin.stopping) return [];
return bitcoindjs.getInfo(); return bitcoindjs.getInfo();

View File

@ -821,6 +821,7 @@ async_get_tx(uv_work_t *req) {
{ {
if (mempool.lookup(hash, ctx)) if (mempool.lookup(hash, ctx))
{ {
data->ctx = ctx;
return; return;
} }
} }
@ -995,6 +996,13 @@ NAN_METHOD(GetMempoolOutputs) {
Local<Array> outputs = Array::New(isolate); Local<Array> outputs = Array::New(isolate);
int arrayIndex = 0; int arrayIndex = 0;
v8::String::Utf8Value param1(args[0]->ToString());
std::string *input = new std::string(*param1);
const char* psz = input->c_str();
std::vector<unsigned char> vAddress;
DecodeBase58(psz, vAddress);
vector<unsigned char> hashBytes(vAddress.begin()+1, vAddress.begin()+21);
std::map<uint256, CTxMemPoolEntry> mapTx = mempool.mapTx; std::map<uint256, CTxMemPoolEntry> mapTx = mempool.mapTx;
for(std::map<uint256, CTxMemPoolEntry>::iterator it = mapTx.begin(); it != mapTx.end(); it++) { for(std::map<uint256, CTxMemPoolEntry>::iterator it = mapTx.begin(); it != mapTx.end(); it++) {
@ -1010,24 +1018,31 @@ NAN_METHOD(GetMempoolOutputs) {
CScript script = txout.scriptPubKey; CScript script = txout.scriptPubKey;
txnouttype type; txnouttype type;
vector<vector<unsigned char> > hash; std::vector<std::vector<unsigned char> > hashResults;
if (Solver(script, type, hashResults)) {
if (Solver(script, type, hash)) {
if (type == TX_PUBKEYHASH || type == TX_SCRIPTHASH) { if (type == TX_PUBKEYHASH || type == TX_SCRIPTHASH) {
Local<Object> output = NanNew<Object>(); vector<unsigned char> scripthashBytes = hashResults.front();
// todo: include the script if(equal(hashBytes.begin(), hashBytes.end(), scripthashBytes.begin())) {
output->Set(NanNew<String>("script"), NanNew<String>(""));
uint64_t satoshis = txout.nValue; Local<Object> output = NanNew<Object>();
output->Set(NanNew<String>("satoshis"), NanNew<Number>(satoshis)); // can't go above 2 ^ 53 -1
output->Set(NanNew<String>("txid"), NanNew<String>(txid.GetHex()));
output->Set(NanNew<String>("outputIndex"), NanNew<Number>(outputIndex)); // todo: include the script
output->Set(NanNew<String>("script"), NanNew<String>(script.ToString()));
outputs->Set(arrayIndex, output); uint64_t satoshis = txout.nValue;
arrayIndex++; output->Set(NanNew<String>("satoshis"), NanNew<Number>(satoshis)); // can't go above 2 ^ 53 -1
output->Set(NanNew<String>("txid"), NanNew<String>(txid.GetHex()));
output->Set(NanNew<String>("outputIndex"), NanNew<Number>(outputIndex));
outputs->Set(arrayIndex, output);
arrayIndex++;
}
} }
} }
@ -1043,19 +1058,17 @@ NAN_METHOD(GetMempoolOutputs) {
* AddMempoolUncheckedTransaction * AddMempoolUncheckedTransaction
*/ */
NAN_METHOD(AddMempoolUncheckedTransaction) { NAN_METHOD(AddMempoolUncheckedTransaction) {
if (!node::Buffer::HasInstance(args[0])) { NanScope();
return NanThrowTypeError("First argument should be a Buffer.");
}
CTransaction tx; v8::String::Utf8Value param1(args[0]->ToString());
const char *arg = node::Buffer::Data(args[0]); std::string *input = new std::string(*param1);
std::string strArg = std::string(arg);
if (!DecodeHexTx(tx, strArg)) { CTransaction tx;
return NanThrowError("could not decode tx"); if (!DecodeHexTx(tx, *input)) {
} return NanThrowError("could not decode tx");
bool added = mempool.addUnchecked(tx.GetHash(), CTxMemPoolEntry(tx, 0, 0, 0.0, 1)); }
NanReturnValue(NanNew<Boolean>(added)); bool added = mempool.addUnchecked(tx.GetHash(), CTxMemPoolEntry(tx, 0, 0, 0.0, 1));
NanReturnValue(NanNew<Boolean>(added));
} }