From 6f5566940a63ede617a77abcb767875803af5413 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 3 Jul 2019 01:32:33 -1100 Subject: [PATCH] Serdes for NSPV structs and initial functionality --- src/komodo_defs.h | 3 + src/komodo_nSPV.h | 570 +++++++++++++++++++++++++++++++++++++++------- 2 files changed, 493 insertions(+), 80 deletions(-) diff --git a/src/komodo_defs.h b/src/komodo_defs.h index 784502dc8..5ea260db6 100644 --- a/src/komodo_defs.h +++ b/src/komodo_defs.h @@ -336,6 +336,9 @@ int32_t komodo_priceget(int64_t *buf64,int32_t ind,int32_t height,int32_t numblo uint64_t komodo_accrued_interest(int32_t *txheightp,uint32_t *locktimep,uint256 hash,int32_t n,int32_t checkheight,uint64_t checkvalue,int32_t tipheight); int32_t komodo_currentheight(); +bool Getscriptaddress(char *destaddr,const CScript &scriptPubKey); +std::vector Mypubkey(); + struct NSPV_spentinfo { uint256 txid,spenttxid; diff --git a/src/komodo_nSPV.h b/src/komodo_nSPV.h index 6c46e049f..e37a83746 100644 --- a/src/komodo_nSPV.h +++ b/src/komodo_nSPV.h @@ -18,6 +18,13 @@ * * ******************************************************************************/ +// todo: make sure no files are updated +// finalize structs, de/serialization +// rpc calls +// validate proofs + +// make sure to sanity check all vector lengths on receipt + #ifndef KOMODO_NSPV_H #define KOMODO_NSPV_H @@ -34,33 +41,15 @@ #define NSPV_SPENTINFO 0x0a #define NSPV_SPENTINFORESP 0x0b -struct NSPV_ntz +int32_t iguana_rwbuf(int32_t rwflag,uint8_t *serialized,uint16_t len,uint8_t *buf) { - uint256 blockhash,txid,othertxid; - int32_t height,txidheight; -}; + if ( rwflag != 0 ) + memcpy(serialized,buf,len); + else memcpy(buf,serialized,len); + return(len) +} -struct NSPV_info -{ - struct NSPV_ntz notarization; - uint256 blockhash; - int32_t height; -}; - -struct NSPV_utxo -{ - uint256 txid; - int64_t satoshis,extradata; - int32_t vout,height,before,after; - std::vector tx,txproof; -}; - -struct NSPV_ntzs -{ - struct NSPV_ntz before,after; -}; - -struct NSPV_equiheader +struct NSPV_equihdr { int32_t nVersion; uint256 hashPrevBlock; @@ -68,106 +57,516 @@ struct NSPV_equiheader uint256 hashFinalSaplingRoot; uint32_t nTime; uint32_t nBits; - CPOSNonce nNonce; + uint256 nNonce; uint8_t nSolution[1344]; }; -struct NSPV_ntzproofhdr +int32_t NSPV_rwequihdr(int32_t rwflag,uint8_t *serialized,struct NSPV_equihdr *ptr) { - std::vector headers; - int32_t beforeheight,afterheight; + int32_t len = 0; + len += iguana_rwnum(rwflag,&serialized[len],sizeof(ptr->nVersion),&ptr->nVersion); + len += iguana_rwbignum(rwflag,&serialized[len],sizeof(ptr->hashPrevBlock),(uint8_t *)&ptr->hashPrevBlock); + len += iguana_rwbignum(rwflag,&serialized[len],sizeof(ptr->hashMerkleRoot),(uint8_t *)&ptr->hashMerkleRoot); + len += iguana_rwbignum(rwflag,&serialized[len],sizeof(ptr->hashFinalSaplingRoot),(uint8_t *)&ptr->hashFinalSaplingRoot); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(ptr->nTime),&ptr->nTime); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(ptr->nBits),&ptr->nBits); + len += iguana_rwbignum(rwflag,&serialized[len],sizeof(ptr->nNonce),(uint8_t *)&ptr->nNonce); + len += iguana_rwbuf(rwflag,&serialized[len],sizeof(ptr->nSolution),ptr->nSolution); + return(len); +} + +int32_t iguana_rwequihdrvec(int32_t rwflag,uint8_t *serialized,uint16_t *vecsizep,uint8_t struct NSPV_equihdr **ptrp) +{ + int32_t i,vsize,len = 0; + len += iguana_rwnum(rwflag,&serialized[len],sizeof(*vecsizep),vecsizep); + if ( (vsize= *vecsizep) != 0 ) + { + if ( *ptrp == 0 ) + *ptrp = calloc(sizeof(**ptrp),vsize); // relies on uint16_t being "small" to prevent mem exhaustion + for (i=0; i beforentz,afterntz; + int32_t len = 0; + len += iguana_rwbignum(rwflag,&serialized[len],sizeof(ptr->txid),(uint8_t *)&ptr->txid); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(ptr->satoshis),&ptr->satoshis); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(ptr->extradata),&ptr->extradata); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(ptr->vout),&ptr->vout); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(ptr->height),&ptr->height); + return(len); +} + +struct NSPV_utxosresp +{ + struct NSPV_utxoresp *utxos; + int64_t total,interest; + int32_t pad32; + uint16_t numutxos,pad16; }; -struct NSPV_MMRproof +int32_t NSPV_rwutxosresp(int32_t rwflag,uint8_t *serialized,uint16_t *vecsizep,uint8_t struct NSPV_utxosresp **ptrp) // check mempool { - struct NSPV_ntzproofhdr hdr; - std::vector mmrproof; + int32_t i,vsize,len = 0; + len += iguana_rwnum(rwflag,&serialized[len],sizeof(*vecsizep),vecsizep); + if ( (vsize= *vecsizep) != 0 ) + { + if ( *ptrp == 0 ) + *ptrp = calloc(sizeof(**ptrp),vsize); // relies on uint16_t being "small" to prevent mem exhaustion + for (i=0; itotal),&ptr->total); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(ptr->interest),&ptr->interest); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(ptr->pad32),&ptr->pad32); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(ptr->pad16),&ptr->pad16); + return(len); +} + +void NSPV_utxosresp_purge(struct NSPV_utxosresp *ptr) +{ + if ( ptr != 0 ) + { + if ( ptr->utxos != 0 ) + free(ptr->utxos); + memset(ptr,0,sizeof(*ptr)); + } +} + +struct NSPV_ntz +{ + uint256 blockhash,txid,othertxid; + int32_t height,txidheight; }; +int32_t NSPV_rwntz(int32_t rwflag,uint8_t *serialized,struct NSPV_ntz *ptr) +{ + int32_t len = 0; + len += iguana_rwbignum(rwflag,&serialized[len],sizeof(ptr->blockhash),(uint8_t *)&ptr->blockhash); + len += iguana_rwbignum(rwflag,&serialized[len],sizeof(ptr->txid),(uint8_t *)&ptr->txid); + len += iguana_rwbignum(rwflag,&serialized[len],sizeof(ptr->othertxid),(uint8_t *)&ptr->othertxid); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(ptr->height),&ptr->height); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(ptr->txidheight),&ptr->txidheight); + return(len); +} + +struct NSPV_ntzsresp +{ + struct NSPV_ntz prevntz,nextntz; +}; + +int32_t NSPV_rwntzsresp(int32_t rwflag,uint8_t *serialized,struct NSPV_ntzsresp *ptr) +{ + int32_t len = 0; + len += NSPV_rwntz(rwflag,&serialized[len],sizeof(ptr->prevntz),&ptr->prevntz); + len += NSPV_rwntz(rwflag,&serialized[len],sizeof(ptr->nextntz),&ptr->nextntz); + return(len); +} + +void NSPV_ntzsresp_purge(struct NSPV_ntzsresp *ptr) +{ + if ( ptr != 0 ) + memset(ptr,0,sizeof(*ptr)); +} + +struct NSPV_inforesp +{ + struct NSPV_ntz notarization; + uint256 blockhash; + int32_t height,pad32; +}; + +int32_t NSPV_rwinforesp(int32_t rwflag,uint8_t *serialized,struct NSPV_inforesp *ptr) +{ + int32_t len = 0; + len += NSPV_rwntz(rwflag,&serialized[len],sizeof(ptr->notarization),&ptr->notarization); + len += iguana_rwbignum(rwflag,&serialized[len],sizeof(ptr->blockhash),(uint8_t *)&ptr->blockhash); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(ptr->height),&ptr->height); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(ptr->pad32),&ptr->pad32); + return(len); +} + +void NSPV_inforesp_purge(struct NSPV_inforesp *ptr) +{ + if ( ptr != 0 ) + memset(ptr,0,sizeof(*ptr)); +} + struct NSPV_txproof { uint256 txid; - std::vector tx,txproof; int32_t height; + uint16_t txlen,txprooflen; + uint8_t *tx,*txproof; }; -uint32_t NSPV_lastinfo,NSPV_lastutxos; -std::vector NSPV_utxos; -std::vector NSPV_spends; +int32_t NSPV_rwtxproof(int32_t rwflag,uint8_t *serialized,struct NSPV_txproof *ptr) +{ + int32_t len = 0; + len += iguana_rwbignum(rwflag,&serialized[len],sizeof(ptr->txid),(uint8_t *)&ptr->txid); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(ptr->height),&ptr->height); + len += iguana_rwuint8vec(rwflag,&serialized[len],&ptr->txlen,&ptr->tx); + len += iguana_rwuint8vec(rwflag,&serialized[len],&ptr->txprooflen,&ptr->txproof); + return(len); +} + +void NSPV_txproof_purge(struct NSPV_txproof *ptr) +{ + if ( ptr != 0 ) + { + if ( ptr->tx != 0 ) + free(ptr->tx); + if ( ptr->txproof != 0 ) + free(ptr->txproof); + memset(ptr,0,sizeof(*ptr)); + } +} + +struct NSPV_utxo +{ + struct NSPV_txproof T; + int64_t satoshis,extradata; + int32_t vout,prevht,nextht,pad32; +}; + +int32_t NSPV_rwutxo(int32_t rwflag,uint8_t *serialized,struct NSPV_utxo *ptr) +{ + int32_t len = 0; + len += NSPV_rwtxproof(rwflag,&serialized[len],&ptr->T); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(ptr->satoshis),&ptr->satoshis); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(ptr->extradata),&ptr->extradata); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(ptr->vout),&ptr->vout); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(ptr->prevht),&ptr->prevht); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(ptr->nextht),&ptr->nextht); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(ptr->pad32),&ptr->pad32); + return(len); +} + +struct NSPV_ntzproofshared +{ + struct NSPV_equihdr *hdrs; + int32_t prevht,nextht,pad32; + uint16_t numhdrs,pad16; +}; + +int32_t NSPV_rwntzproofshared(int32_t rwflag,uint8_t *serialized,struct NSPV_ntzproofshared *ptr) +{ + int32_t len = 0; + len += iguana_rwequihdrvec(rwflag,&serialized[len],&ptr->numhdrs,&ptr->hdrs); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(ptr->prevht),&ptr->prevht); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(ptr->nextht),&ptr->nextht); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(ptr->pad32),&ptr->pad32); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(ptr->pad16),&ptr->pad16); + return(len); +} + +struct NSPV_ntzsproofresp +{ + struct NSPV_ntzproofshared common; + uint32_t pad32; + uint16_t prevlen,nextlen; + uint8_t *prevntz,*nextntz; +}; + +int32_t NSPV_rwntzproof(int32_t rwflag,uint8_t *serialized,struct NSPV_ntzsproofresp *ptr) +{ + int32_t len = 0; + len += NSPV_rwntzproofshared(rwflag,&serialized[len],&ptr->common); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(ptr->pad32),&ptr->pad32); + len += iguana_rwuint8vec(rwflag,&serialized[len],&ptr->prevlen,&ptr->prevntz); + len += iguana_rwuint8vec(rwflag,&serialized[len],&ptr->nextlen,&ptr->nextntz); + return(len); +} + +void NSPV_ntzsproofresp_purge(struct NSPV_ntzsproofresp *ptr) +{ + if ( ptr != 0 ) + { + if ( ptr->common.hdrs != 0 ) + free(ptr->common.hdrs); + if ( ptr->prevntz != 0 ) + free(ptr->prevntz); + if ( ptr->nextntz != 0 ) + free(ptr->nextntz); + memset(ptr,0,sizeof(*ptr)); + } +} + +struct NSPV_MMRproof +{ + struct NSPV_ntzproofhdr hdr; + // tbd +}; + +struct NSPV_spentinfo +{ + struct NSPV_txproof spent; + uint256 txid; + int32_t height,spentvini; +}; + +int32_t NSPV_rwspentinfo(int32_t rwflag,uint8_t *serialized,struct NSPV_spentinfo *ptr) // check mempool +{ + int32_t len = 0; + len += NSPV_rwtxproof(rwflag,&serialized[len],&ptr->spent); + len += iguana_rwbignum(rwflag,&serialized[len],sizeof(ptr->txid),(uint8_t *)&ptr->txid); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(ptr->height),&ptr->height); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(ptr->spentvini),&ptr->spentvini); + return(len); +} + +void NSPV_spentinfo_purge(struct NSPV_spentinfo *ptr) +{ + if ( ptr != 0 ) + { + NSPV_txproof_purge(&ptr->spent); + memset(ptr,0,sizeof(*ptr)); + } +} // on fullnode: + +int32_t NSPV_getinfo(struct NSPV_inforesp *ptr) +{ + int32_t prevMoMheight,len = 0; CBlockIndex *pindex; + if ( (pindex= chainActive.LastTip()) != 0 ) + { + ptr->height = pindex->GetHeight(); + ptr->blockhash = pindex->GetBlockHash(); + ptr->notarization.height = komodo_notarized_height(&prevMoMheight,&ptr->notarization.blockhash,&ptr->notarization.othertxid); + //ptr->notarization.txidheight = komodo_findnotarization(&ptr->notarization.txid,ptr->notarization.height,ptr->notarization.blockhash); + return(sizeof(*ptr)); + } else return(-1); +} + +int32_t NSPV_getaddressutxos(struct NSPV_utxosresp *ptr,char *coinaddr) // check mempool +{ + int64_t total = 0,interest=0; uint32_t locktime; int32_t tipheight,txheight,n = 0,len = 0; + std::vector > unspentOutputs; + fprintf(stderr,"getaddressutxos for %s\n",coinaddr); + SetCCunspents(unspentOutputs,coinaddr,false); + if ( (ptr->numutxos= (int32_t)unspentOutputs.size()) > 0 ) + { + tipheight = chainActive.LastTip()->GetHeight(); + ptr->utxos = calloc(ptr->numutxos,sizeof(*ptr->utxos)); + for (std::vector >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++) + { + ptr->utxos[n].txid = it->first.txhash; + ptr->utxos[n].vout = (int32_t)it->first.index; + ptr->utxos[n].satoshis = it->second.satoshis; + ptr->utxos[n].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[n].txid,ptr->utxos[n].vout,ptr->utxos[n].height,ptr->utxos[n].satoshis,tipheight); + interest += ptr->utxos[n].extradata; + } + total += it->second.satoshis; + n++; + } + fprintf(stderr,"getaddressutxos for %s -> n.%d total %.8f interest %.8f\n",coinaddr,dstr(total),dstr(interest)); + if ( n == ptr->numutxos ) + { + ptr->total = total; + ptr->interest = interest; + return((int32_t)(sizeof(*ptr) + sizeof(*ptr->utxos)*ptr->numutxos)); + } + } + if ( ptr->utxos != 0 ) + free(ptr->utxos); + memst(ptr,0,sizeof(*ptr)); + return(0); +} + +int32_t NSPV_getntzsresp(struct NSPV_ntzsresp *ptr,int32_t height) +{ + int32_t len = 0; + return(sizeof(*ptr)); +} + +int32_t NSPV_getntzsproofresp(struct NSPV_ntzsproofresp *ptr,int32_t prevht,int32_t nextht) +{ + int32_t len = 0; + return(len); +} + +int32_t NSPV_gettxproof(struct NSPV_txproof *ptr,uint256 txid,int32_t height) +{ + int32_t len = 0; + return(len); +} + +int32_t NSPV_getspentinfo(struct NSPV_spentinfo *ptr,uint256 txid,int32_t vout) +{ + int32_t len = 0; + return(len); +} + void komodo_nSPVreq(CNode *pfrom,std::vector request) // received a request { - int32_t len; std::vector response; uint32_t timestamp = (uint32_t)time(NULL); + int32_t len,slen; std::vector response; uint32_t timestamp; + timestamp = (uint32_t)time(NULL); if ( (len= request.size()) > 0 ) { - response.resize(1); - if ( len == 1 && request[0] == NSPV_INFO ) // info + if ( request[0] == NSPV_INFO ) // info { if ( timestamp > pfrom->lastinfo + ASSETCHAINS_BLOCKTIME/2 ) { - response[0] = NSPV_INFORESP; - pfrom->lastinfo = timestamp; - pfrom->PushMessage("nSPV",response); + struct NSPV_inforesp I; + memset(&I,0,sizeof(I)); + if ( (slen= NSPV_getinfo(&I)) > 0 ) + { + response.resize(1 + slen); + response[0] = NSPV_INFORESP; + NSPV_rwinforesp(1,&response[1],&I); + pfrom->PushMessage("nSPV",response); + pfrom->lastinfo = timestamp; + NSPV_inforesp_purge(&I); + } } } else if ( request[0] == NSPV_UTXOS ) { if ( timestamp > pfrom->lastutxos + ASSETCHAINS_BLOCKTIME/2 ) { - response[0] = NSPV_UTXOSRESP; - pfrom->lastutxos = timestamp; - // check mempool - pfrom->PushMessage("nSPV",response); + struct NSPV_utxosresp U; char coinaddr[64]; + if ( len < 64 && request[1] == len-2 ) + { + memcpy(coinaddr,&request[2],request[1]); + memset(&U,0,sizeof(U)); + slen = NSPV_getaddressutxos(&U,coinaddr); + response.resize(1 + slen); + response[0] = NSPV_UTXOSRESP; + if ( NSPV_rwutxosresp(1,&response[1],&U.numutxos,&U.utxos) == slen ) + { + pfrom->PushMessage("nSPV",response); + pfrom->lastutxos = timestamp; + } + NSPV_utxosresp_purge(&U); + } } } else if ( request[0] == NSPV_NTZS ) { if ( timestamp > pfrom->lastntzs ) { - response[0] = NSPV_NTZSRESP; - pfrom->lastntzs = timestamp; - pfrom->PushMessage("nSPV",response); + struct NSPV_ntzsresp N; int32_t height; + if ( len == 1+sizeof(height) ) + { + iguana_rwnum(rwflag,&request[1],sizeof(height),&height); + memset(&N,0,sizeof(N)); + slen = NSPV_getntzsresp(&N,height); + response.resize(1 + slen); + response[0] = NSPV_NTZSRESP; + if ( NSPV_rwntzsresp(1,&response[1],&N) == slen ) + { + pfrom->PushMessage("nSPV",response); + pfrom->lastntzs = timestamp; + } + NSPV_ntzsresp_purge(&N); + } } } else if ( request[0] == NSPV_NTZPROOF ) { if ( timestamp > pfrom->lastproof ) { - response[0] = NSPV_NTZPROOFRESP; - pfrom->lastproof = timestamp; - pfrom->PushMessage("nSPV",response); + struct NSPV_ntzsproofresp P; int32_t prevht,nextht; + if ( len == 1+sizeof(prevht)+sizeof(nextht) ) + { + iguana_rwnum(rwflag,&request[1],sizeof(prevht),&prevht); + iguana_rwnum(rwflag,&request[1+sizeof(prevht)],sizeof(nextht),&nextht); + if ( prevht != 0 && nextht != 0 && nextht >= prevht ) + { + memset(&N,0,sizeof(N)); + slen = NSPV_getntzsproofresp(&P,prevht,nextht); + response.resize(1 + slen); + response[0] = NSPV_NTZPROOFRESP; + if ( NSPV_rwntzsresp(1,&response[1],&P) == slen ) + { + pfrom->PushMessage("nSPV",response); + pfrom->lastproof = timestamp; + } + NSPV_ntzsproofresp_purge(&P); + } + } } } else if ( request[0] == NSPV_TXPROOF ) { if ( timestamp > pfrom->lastproof ) { - response[0] = NSPV_TXPROOFRESP; - pfrom->lastproof = timestamp; - pfrom->PushMessage("nSPV",response); + struct NSPV_spentinfo P; uint256 txid; int32_t height; + if ( len == 1+sizeof(txid)+sizeof(height) ) + { + iguana_rwnum(rwflag,&request[1],sizeof(height),&height); + iguana_rwbignum(rwflag,&request[1+sizeof(height)],sizeof(txid),(uint8_t *)&txid); + memset(&P,0,sizeof(P)); + slen = NSPV_gettxproof(&P,txid,height); + response.resize(1 + slen); + response[0] = NSPV_TXPROOFRESP; + if ( NSPV_rwtxproof(1,&response[1],&P) == slen ) + { + pfrom->PushMessage("nSPV",response); + pfrom->lastproof = timestamp; + } + NSPV_txproof_purge(&P); + } } } else if ( request[0] == NSPV_SPENTINFO ) { if ( timestamp > pfrom->lastspent ) { - response[0] = NSPV_SPENTINFORESP; - // check mempool - pfrom->lastspent = timestamp; - pfrom->PushMessage("nSPV",response); + struct NSPV_spentinfo S; int32_t vout; uint256 txid; + if ( len == 1+sizeof(txid)+sizeof(vout) ) + { + iguana_rwnum(rwflag,&request[1],sizeof(vout),&vout); + iguana_rwbignum(rwflag,&request[1+sizeof(vout)],sizeof(txid),(uint8_t *)&txid); + memset(&S,0,sizeof(S)); + slen = NSPV_getspentinfo(&S,txid,vout); + response.resize(1 + slen); + response[0] = NSPV_SPENTINFORESP; + if ( NSPV_rwspentinfo(1,&response[1],&S) == slen ) + { + pfrom->PushMessage("nSPV",response); + pfrom->lastspent = timestamp; + } + NSPV_spentinfo_purge(&S); + } } } } } // on nSPV client +uint32_t NSPV_lastinfo,NSPV_lastutxos; +int32_t NSPV_numutxos,NSPV_numspends; +struct NSPV_utxo *NSPV_utxos; +struct NSPV_spentinfo *NSPV_spends; + void komodo_nSPVresp(CNode *pfrom,std::vector response) // received a response { int32_t len; uint32_t timestamp = (uint32_t)time(NULL); @@ -176,22 +575,22 @@ void komodo_nSPVresp(CNode *pfrom,std::vector response) // received a r switch ( response[0] ) { case NSPV_INFORESP: - fprintf(stderr,"got info response %u\n",timestamp); // update current height and ntrz status + fprintf(stderr,"got info response %u size.%d\n",timestamp,(int32_t)response.size()); // update current height and ntrz status break; case NSPV_UTXOSRESP: - fprintf(stderr,"got utxos response %u\n",timestamp); // update utxos list + fprintf(stderr,"got utxos response %u size.%d\n",timestamp,(int32_t)response.size()); // update utxos list break; case NSPV_NTZSRESP: - fprintf(stderr,"got ntzs response %u\n",timestamp); // update utxos[i] + fprintf(stderr,"got ntzs response %u size.%d\n",timestamp,(int32_t)response.size()); // update utxos[i] break; case NSPV_NTZPROOFRESP: - fprintf(stderr,"got ntzproof response %u\n",timestamp); // update utxos[i] + fprintf(stderr,"got ntzproof response %u size.%d\n",timestamp,(int32_t)response.size()); // update utxos[i] break; case NSPV_TXPROOFRESP: - fprintf(stderr,"got txproof response %u\n",timestamp); // update utxos[i] + fprintf(stderr,"got txproof response %u size.%d\n",timestamp,(int32_t)response.size()); // update utxos[i] break; case NSPV_SPENTINFORESP: - fprintf(stderr,"got spentinfo response %u\n",timestamp); // update utxos[i] + fprintf(stderr,"got spentinfo response %u size.%d\n",timestamp,(int32_t)response.size()); // update utxos[i] break; default: fprintf(stderr,"unexpected response %02x size.%d at %u\n",response[0],(int32_t)response.size(),timestamp); break; @@ -201,14 +600,17 @@ void komodo_nSPVresp(CNode *pfrom,std::vector response) // received a r void komodo_NSPV_spentinfoclear() { - NSPV_spends.resize(0); + if ( NSPV_spends != 0 ) + free(NSPV_spends); + NSPV_spends = 0; + NSPV_numspends = 0; } struct NSPV_spentinfo komodo_NSPV_spentinfo(uint256 txid,int32_t vout) // just a primitive example of how to add new rpc to p2p msg { - std::vector request; struct NSPV_spentinfo I; int32_t i,numsent = 0; uint32_t timestamp = (uint32_t)time(NULL); - // lookup spentinfo - for (i=0; i request; struct NSPV_spentinfo I; int32_t i,numsent = 0; uint32_t timestamp; + timestamp = (uint32_t)time(NULL); + for (i=0; ihSocket == INVALID_SOCKET ) continue; - if ( (pnode->nServices & NODE_NSPV) != 0 && timestamp > pnode->lastspent ) + if ( (pnode->nServices & NODE_SPENTINDEX) != 0 && timestamp > pnode->lastspent ) { request.resize(1); request[0] = NSPV_SPENTINFO; @@ -238,12 +640,12 @@ void komodo_nSPV(CNode *pto) return; if ( timestamp > pto->lastntzs || timestamp > pto->lastproof ) { - for (i=0; i pto->lastntzs ) + if ( NSPV_utxos[i].prevlen == 0 && timestamp > pto->lastntzs ) { request[0] = NSPV_NTZS; pto->lastntzs = timestamp; @@ -276,10 +678,18 @@ void komodo_nSPV(CNode *pto) // get utxo since lastheight if ( (rand() % 100) < 10 ) { - request.resize(1); - request[0] = NSPV_UTXOS; - NSPV_lastutxos = pto->lastutxos = timestamp; - pto->PushMessage("getnSPV",request); + char coinaddr[64]; int32_t slen; + Getscriptaddress(coinaddr,CScript() << Mypubkey() << OP_CHECKSIG); + slen = (int32_t)strlen(coinaddr); + if ( slen < 64 ) + { + request.resize(1 + 1 + slen); + request[0] = NSPV_UTXOS; + request[1] = slen; + memcpy(&request[2],coinaddr,slen); + NSPV_lastutxos = pto->lastutxos = timestamp; + pto->PushMessage("getnSPV",request); + } } } }