Browse Source

First version of mempool request

warmup
jl777 5 years ago
parent
commit
28e10d71bf
  1. 55
      src/komodo_nSPV.h
  2. 12
      src/komodo_nSPV_defs.h
  3. 133
      src/komodo_nSPV_fullnode.h
  4. 42
      src/komodo_nSPV_superlite.h
  5. 1
      src/rpc/server.cpp
  6. 1
      src/rpc/server.h
  7. 21
      src/wallet/rpcdump.cpp

55
src/komodo_nSPV.h

@ -18,13 +18,12 @@
// new p2p messages: getrawmempool and support myIsutxo_spentinmempool and mytxid_inmempool
// myprivkey, scrub all destination buffers
// make req for utxo/txid more sane?
// headers "sync" make sure it connects to prior blocks to notarization. use getinfo hdrht to get missing hdrs
// Myprivkey(uint8_t *privkey), scrub all destination privkey buffers
// make sure to sanity check all vector lengths on receipt
// make sure no files are updated (this is to allow nSPV=1 and later nSPV=0 without affecting database)
// make req for utxo/txid more sane? (optional)
// bug: under load, fullnode was returning all 0 nServices
#ifndef KOMODO_NSPV_H
@ -200,6 +199,56 @@ void NSPV_txidsresp_copy(struct NSPV_txidsresp *dest,struct NSPV_txidsresp *ptr)
}
}
int32_t NSPV_rwmempoolresp(int32_t rwflag,uint8_t *serialized,struct NSPV_mempoolresp *ptr)
{
int32_t i,len = 0;
len += iguana_rwnum(rwflag,&serialized[len],sizeof(ptr->numtxids),&ptr->numtxids);
if ( ptr->numtxids != 0 )
{
if ( ptr->txids == 0 )
ptr->txids = (uint256 *)calloc(sizeof(*ptr->txids),ptr->numtxids);
for (i=0; i<ptr->numtxids; i++)
len += NSPV_rwtxidresp(rwflag,&serialized[len],&ptr->txids[i]);
}
len += iguana_rwnum(rwflag,&serialized[len],sizeof(ptr->nodeheight),&ptr->nodeheight);
len += iguana_rwnum(rwflag,&serialized[len],sizeof(ptr->vout),&ptr->vout);
len += iguana_rwnum(rwflag,&serialized[len],sizeof(ptr->pad32),&ptr->pad32);
len += iguana_rwnum(rwflag,&serialized[len],sizeof(ptr->CCflag),&ptr->CCflag);
len += iguana_rwnum(rwflag,&serialized[len],sizeof(ptr->funcid),&ptr->funcid);
if ( rwflag != 0 )
{
memcpy(&serialized[len],ptr->coinaddr,sizeof(ptr->coinaddr));
len += sizeof(ptr->coinaddr);
}
else
{
memcpy(ptr->coinaddr,&serialized[len],sizeof(ptr->coinaddr));
len += sizeof(ptr->coinaddr);
}
fprintf(stderr,"NSPV_rwmempoolresp rwlen.%d\n",len);
return(len);
}
void NSPV_mempoolresp_purge(struct NSPV_mempoolresp *ptr)
{
if ( ptr != 0 )
{
if ( ptr->txids != 0 )
free(ptr->txids);
memset(ptr,0,sizeof(*ptr));
}
}
void NSPV_mempoolresp_copy(struct NSPV_mempoolresp *dest,struct NSPV_mempoolresp *ptr)
{
*dest = *ptr;
if ( ptr->txids != 0 )
{
dest->txids = (uint256 *)malloc(ptr->numtxids * sizeof(*ptr->txids));
memcpy(dest->txids,ptr->txids,ptr->numtxids * sizeof(*ptr->txids));
}
}
int32_t NSPV_rwntz(int32_t rwflag,uint8_t *serialized,struct NSPV_ntz *ptr)
{
int32_t len = 0;

12
src/komodo_nSPV_defs.h

@ -43,6 +43,10 @@
#define NSPV_TXIDSRESP 0x0f
#define NSPV_MEMPOOL 0x10
#define NSPV_MEMPOOLRESP 0x11
#define NSPV_MEMPOOL_ALL 0
#define NSPV_MEMPOOL_ADDRESS 1
#define NSPV_MEMPOOL_ISSPENT 2
#define NSPV_MEMPOOL_INMEMPOOL 3
int32_t NSPV_gettransaction(int32_t skipvalidation,int32_t vout,uint256 txid,int32_t height,CTransaction &tx,int64_t extradata,uint32_t tiptime,int64_t &rewardsum);
UniValue NSPV_spend(char *srcaddr,char *destaddr,int64_t satoshis);
@ -92,6 +96,14 @@ struct NSPV_txidsresp
uint16_t numtxids,CCflag;
};
struct NSPV_mempoolresp
{
uint256 *txids;
char coinaddr[64];
int32_t nodeheight,vout,pad32;
uint16_t numtxids; uint8_t CCflag,funcid;
};
struct NSPV_ntz
{
uint256 blockhash,txid,othertxid;

133
src/komodo_nSPV_fullnode.h

@ -157,26 +157,29 @@ int32_t NSPV_getaddressutxos(struct NSPV_utxosresp *ptr,char *coinaddr,bool isCC
if ( skipcount >= ptr->numutxos )
skipcount = ptr->numutxos-1;
ptr->skipcount = skipcount;
ptr->utxos = (struct NSPV_utxoresp *)calloc(ptr->numutxos-skipcount,sizeof(*ptr->utxos));
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++)
if ( ptr->numutxos-skipcount > 0 )
{
// if gettxout is != null to handle mempool
ptr->utxos = (struct NSPV_utxoresp *)calloc(ptr->numutxos-skipcount,sizeof(*ptr->utxos));
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++)
{
if ( n >= skipcount )
// if gettxout is != null to handle mempool
{
ptr->utxos[ind].txid = it->first.txhash;
ptr->utxos[ind].vout = (int32_t)it->first.index;
ptr->utxos[ind].satoshis = it->second.satoshis;
ptr->utxos[ind].height = it->second.blockHeight;
if ( ASSETCHAINS_SYMBOL[0] == 0 && it->second.satoshis >= 10*COIN )
if ( n >= skipcount )
{
ptr->utxos[n].extradata = komodo_accrued_interest(&txheight,&locktime,ptr->utxos[ind].txid,ptr->utxos[ind].vout,ptr->utxos[ind].height,ptr->utxos[ind].satoshis,tipheight);
interest += ptr->utxos[ind].extradata;
ptr->utxos[ind].txid = it->first.txhash;
ptr->utxos[ind].vout = (int32_t)it->first.index;
ptr->utxos[ind].satoshis = it->second.satoshis;
ptr->utxos[ind].height = it->second.blockHeight;
if ( ASSETCHAINS_SYMBOL[0] == 0 && it->second.satoshis >= 10*COIN )
{
ptr->utxos[n].extradata = komodo_accrued_interest(&txheight,&locktime,ptr->utxos[ind].txid,ptr->utxos[ind].vout,ptr->utxos[ind].height,ptr->utxos[ind].satoshis,tipheight);
interest += ptr->utxos[ind].extradata;
}
ind++;
total += it->second.satoshis;
}
ind++;
total += it->second.satoshis;
n++;
}
n++;
}
}
ptr->numutxos = ind;
@ -209,22 +212,24 @@ int32_t NSPV_getaddresstxids(struct NSPV_txidsresp *ptr,char *coinaddr,bool isCC
skipcount = 0;
if ( (ptr->numtxids= (int32_t)txids.size()) >= 0 && ptr->numtxids < maxlen )
{
// scan mempool add to end
if ( skipcount >= ptr->numtxids )
skipcount = ptr->numtxids-1;
ptr->skipcount = skipcount;
ptr->txids = (struct NSPV_txidresp *)calloc(ptr->numtxids-skipcount,sizeof(*ptr->txids));
for (std::vector<std::pair<CAddressIndexKey, CAmount> >::const_iterator it=txids.begin(); it!=txids.end(); it++)
if ( ptr->numtxids-skipcount > 0 )
{
if ( n >= skipcount )
ptr->txids = (struct NSPV_txidresp *)calloc(ptr->numtxids-skipcount,sizeof(*ptr->txids));
for (std::vector<std::pair<CAddressIndexKey, CAmount> >::const_iterator it=txids.begin(); it!=txids.end(); it++)
{
ptr->txids[ind].txid = it->first.txhash;
ptr->txids[ind].vout = (int32_t)it->first.index;
ptr->txids[ind].satoshis = (int64_t)it->second;
ptr->txids[ind].height = (int64_t)it->first.blockHeight;
ind++;
if ( n >= skipcount )
{
ptr->txids[ind].txid = it->first.txhash;
ptr->txids[ind].vout = (int32_t)it->first.index;
ptr->txids[ind].satoshis = (int64_t)it->second;
ptr->txids[ind].height = (int64_t)it->first.blockHeight;
ind++;
}
n++;
}
n++;
}
ptr->numtxids = ind;
len = (int32_t)(sizeof(*ptr) + sizeof(*ptr->txids)*ptr->numtxids - sizeof(ptr->txids));
@ -236,6 +241,52 @@ int32_t NSPV_getaddresstxids(struct NSPV_txidsresp *ptr,char *coinaddr,bool isCC
return(0);
}
/*struct NSPV_mempoolresp
{
uint256 *txids;
char coinaddr[64];
int32_t nodeheight;
uint16_t numtxids; uint8_t CCflag,funcid;
};
#define NSPV_MEMPOOL_ALL 0
#define NSPV_MEMPOOL_ADDRESS 1
#define NSPV_MEMPOOL_ISSPENT 2
#define NSPV_MEMPOOL_INMEMPOOL 3
*/
int32_t NSPV_mempoolfuncs(std::vector<uint256> &txids,char *coinaddr,bool isCC,uint8_t funcid,uint256 txid)
{
}
int32_t NSPV_mempooltxids(struct NSPV_mempoolresp *ptr,char *coinaddr,bool isCC,uint8_t funcid,uint256 txid,int32_t vout)
{
std::vector<uint256> txids; int32_t i,len = 0;
ptr->nodeheight = chainActive.LastTip()->GetHeight();
strncpy(ptr->coinaddr,coinaddr,sizeof(ptr->coinaddr)-1);
ptr->CCflag = isCC;
ptr->txid = txid;
ptr->vout = vout;
ptr->funcid = funcid;
NSPV_mempoolfuncs(txids,coinaddr,isCC,funcid,txid);
if ( (ptr->numtxids= (int32_t)txids.size()) >= 0 )
{
if ( ptr->numtxids > 0 )
{
ptr->txids = (uint256 *)calloc(ptr->numtxids,sizeof(*ptr->txids));
for (i=0; i<ptr->numtxids; i++)
iguana_rwbignum(0,&txids[i],sizeof(*ptr->txids),(uint8_t *)&ptr->txids[i]);
}
len = (int32_t)(sizeof(*ptr) + sizeof(*ptr->txids)*ptr->numtxids - sizeof(ptr->txids));
return(len);
}
if ( ptr->txids != 0 )
free(ptr->txids);
memset(ptr,0,sizeof(*ptr));
return(0);
}
uint8_t *NSPV_getrawtx(CTransaction &tx,uint256 &hashBlock,int32_t *txlenp,uint256 txid)
{
uint8_t *rawtx = 0;
@ -383,7 +434,7 @@ int32_t NSPV_getspentinfo(struct NSPV_spentinfo *ptr,uint256 txid,int32_t vout)
void komodo_nSPVreq(CNode *pfrom,std::vector<uint8_t> request) // received a request
{
int32_t len,slen,ind,reqheight; std::vector<uint8_t> response; uint32_t timestamp = (uint32_t)time(NULL);
int32_t len,slen,ind,reqheight,n; std::vector<uint8_t> response; uint32_t timestamp = (uint32_t)time(NULL);
if ( (len= request.size()) > 0 )
{
if ( (ind= request[0]>>1) >= sizeof(pfrom->prevtimes)/sizeof(*pfrom->prevtimes) )
@ -485,6 +536,38 @@ void komodo_nSPVreq(CNode *pfrom,std::vector<uint8_t> request) // received a req
} else fprintf(stderr,"len.%d req1.%d\n",len,request[1]);
}
}
else if ( request[0] == NSPV_MEMPOOL )
{
if ( timestamp > pfrom->prevtimes[ind] )
{
struct NSPV_mempoolresp M; char coinaddr[64];
if ( len < sizeof(M)+64 )
{
int32_t vout; uint256 txid; uint8_t funcid,isCC = 0;
n = 1;
len += iguana_rwnum(0,&request[len],sizeof(funcid),&funcid);
len += iguana_rwnum(0,&request[len],sizeof(vout),&vout);
len += iguana_rwbignum(0,&request[len],sizeof(txid),(uint8_t *)&txid);
slen = request[len++];
memcpy(coinaddr,&request[len],slen), len += slen;
//if ( isCC != 0 )
fprintf(stderr,"(%s) isCC.%d funcid.%d %s/v%d\n",coinaddr,isCC,funcid,txid.GetHex().c_str(),vout);
memset(&M,0,sizeof(M));
if ( (slen= NSPV_mempooltxids(&M,coinaddr,isCC,funcid,txid,vout)) > 0 )
{
fprintf(stderr,"NSPV_mempooltxids slen.%d\n",slen);
response.resize(1 + slen);
response[0] = NSPV_MEMPOOLRESP;
if ( NSPV_rwmempoolresp(1,&response[1],&M) == slen )
{
pfrom->PushMessage("nSPV",response);
pfrom->prevtimes[ind] = timestamp;
}
NSPV_mempoolresp_purge(&T);
}
} else fprintf(stderr,"len.%d req1.%d\n",len,request[1]);
}
}
else if ( request[0] == NSPV_NTZS )
{
if ( timestamp > pfrom->prevtimes[ind] )

42
src/komodo_nSPV_superlite.h

@ -32,6 +32,7 @@ std::string NSPV_address;
struct NSPV_inforesp NSPV_inforesult;
struct NSPV_utxosresp NSPV_utxosresult;
struct NSPV_txidsresp NSPV_txidsresult;
struct NSPV_mempoolresp NSPV_mempoolresult;
struct NSPV_spentinfo NSPV_spentresult;
struct NSPV_ntzsresp NSPV_ntzsresult;
struct NSPV_ntzsproofresp NSPV_ntzsproofresult;
@ -166,7 +167,12 @@ void komodo_nSPVresp(CNode *pfrom,std::vector<uint8_t> response) // received a r
NSPV_rwtxidsresp(0,&response[1],&NSPV_txidsresult);
fprintf(stderr,"got txids response %u size.%d %s CC.%d num.%d\n",timestamp,(int32_t)response.size(),NSPV_txidsresult.coinaddr,NSPV_txidsresult.CCflag,NSPV_txidsresult.numtxids);
break;
case NSPV_NTZSRESP:
case NSPV_MEMPOOLRESP:
NSPV_mempoolresp_purge(&NSPV_mempoolresult);
NSPV_rwmempoolresp(0,&response[1],&NSPV_mempoolresult);
fprintf(stderr,"got mempool response %u size.%d %s CC.%d num.%d funcid.%d\n",timestamp,(int32_t)response.size(),NSPV_mempoolresult.coinaddr,NSPV_mempoolresult.CCflag,NSPV_mempoolresult.numtxids,NSPV_mempoolresult.funcid);
break;
case NSPV_NTZSRESP:
NSPV_ntzsresp_purge(&NSPV_ntzsresult);
NSPV_rwntzsresp(0,&response[1],&NSPV_ntzsresult);
if ( NSPV_ntzsresp_find(NSPV_ntzsresult.reqheight) == 0 )
@ -630,6 +636,40 @@ UniValue NSPV_addresstxids(char *coinaddr,int32_t CCflag,int32_t skipcount)
return(result);
}
UniValue NSPV_mempooltxids(char *coinaddr,int32_t CCflag,uint8_t funcid,uint256 txid,int32_t vout)
{
UniValue result(UniValue::VOBJ); uint8_t msg[64]; int32_t i,iter,slen,len = 0;
NSPV_mempoolresp_purge(&NSPV_mempoolresult);
if ( coinaddr[0] != 0 && bitcoin_base58decode(msg,coinaddr) != 25 )
{
result.push_back(Pair("result","error"));
result.push_back(Pair("error","invalid address"));
return(result);
}
slen = (int32_t)strlen(coinaddr);
msg[len++] = NSPV_MEMPOOL;
msg[len++] = (CCflag != 0);
len += iguana_rwnum(1,&msg[len],sizeof(funcid),&funcid);
len += iguana_rwnum(1,&msg[len],sizeof(vout),&vout);
len += iguana_rwbignum(1,&msg[len],sizeof(txid),(uint8_t *)&txid);
msg[len++] = slen;
memcpy(&msg[len],coinaddr,slen), len += slen;
for (iter=0; iter<3; iter++);
if ( NSPV_req(0,msg,len,NODE_NSPV,msg[0]>>1) != 0 )
{
for (i=0; i<NSPV_POLLITERS; i++)
{
usleep(NSPV_POLLMICROS);
if ( NSPV_mempoolresult.nodeheight >= NSPV_inforesult.height && strcmp(coinaddr,NSPV_mempoolresult.coinaddr) == 0 && CCflag == NSPV_mempoolresult.CCflag && txid == NSPV_mempoolresult.txid && vout == NSPV_mempoolresult.vout && funcid == NSPV_mempoolresult.funcid )
return(NSPV_mempoolresp_json(&NSPV_mempoolresult));
}
} else sleep(1);
result.push_back(Pair("result","error"));
result.push_back(Pair("error","no txid result"));
result.push_back(Pair("lastpeer",NSPV_lastpeer));
return(result);
}
UniValue NSPV_notarizations(int32_t reqheight)
{
uint8_t msg[64]; int32_t i,iter,len = 0; struct NSPV_ntzsresp N,*ptr;

1
src/rpc/server.cpp

@ -420,6 +420,7 @@ static const CRPCCommand vRPCCommands[] =
{ "nSPV", "nspv_getinfo", &nspv_getinfo, true },
{ "nSPV", "nspv_login", &nspv_login, true },
{ "nSPV", "nspv_listunspent", &nspv_listunspent, true },
{ "nSPV", "nspv_mempool", &nspv_mempool, true },
{ "nSPV", "nspv_listtransactions",&nspv_listtransactions, true },
{ "nSPV", "nspv_spentinfo", &nspv_spentinfo, true },
{ "nSPV", "nspv_notarizations", &nspv_notarizations, true },

1
src/rpc/server.h

@ -468,6 +468,7 @@ extern UniValue importgatewayprocessed(const UniValue& params, bool fHelp);
extern UniValue nspv_getinfo(const UniValue& params, bool fHelp);
extern UniValue nspv_login(const UniValue& params, bool fHelp);
extern UniValue nspv_listtransactions(const UniValue& params, bool fHelp);
extern UniValue nspv_mempool(const UniValue& params, bool fHelp);
extern UniValue nspv_listunspent(const UniValue& params, bool fHelp);
extern UniValue nspv_spentinfo(const UniValue& params, bool fHelp);
extern UniValue nspv_notarizations(const UniValue& params, bool fHelp);

21
src/wallet/rpcdump.cpp

@ -977,6 +977,7 @@ UniValue NSPV_login(char *wifstr);
UniValue NSPV_logout();
UniValue NSPV_addresstxids(char *coinaddr,int32_t CCflag,int32_t skipcount);
UniValue NSPV_addressutxos(char *coinaddr,int32_t CCflag,int32_t skipcount);
UniValue NSPV_mempooltxids(char *coinaddr,int32_t CCflag,uint8_t funcid,uint256 txid,int32_t vout);
UniValue NSPV_broadcast(char *hex);
UniValue NSPV_spend(char *srcaddr,char *destaddr,int64_t satoshis);
UniValue NSPV_spentinfo(uint256 txid,int32_t vout);
@ -1032,6 +1033,26 @@ UniValue nspv_listunspent(const UniValue& params, bool fHelp)
else throw runtime_error("nspv_listunspent [address [isCC [skipcount]]]\n");
}
UniValue nspv_mempool(const UniValue& params, bool fHelp)
{
UniValue NSPV_mempooltxids(char *coinaddr,int32_t CCflag,uint8_t funcid,uint256 txid,int32_t vout);
int32_t vout = 0,CCflag = 0; uint256 txid; uint8_t funcid; char *coinaddr;
memset(&txid,0,sizeof(txid));
if ( fHelp || params.size() > 5 )
throw runtime_error("nspv_mempool func(0 all, 1 address, 2 txid spent, 3 txid inmempool) address isCC [txid vout]]]\n");
funcid = atoi((char *)params[0].get_str().c_str());
coinaddr = (char *)params[1].get_str().c_str);
CCflag = atoi((char *)params[2].get_str().c_str());
if ( params.size() > 3 )
{
if ( params.size() != 5 )
throw runtime_error("nspv_mempool func(0 all, 1 address, 2 txid spent, 3 txid inmempool) address isCC [txid vout]]]\n");
txid = Parseuint256((char *)params[3].get_str().c_str());
vout = atoi((char *)params[4].get_str().c_str());
}
return(NSPV_mempooltxids(coinaddr,CCflag,funcid,txid,vout));
}
UniValue nspv_listtransactions(const UniValue& params, bool fHelp)
{
int32_t skipcount = 0,CCflag = 0;

Loading…
Cancel
Save