diff --git a/src/komodo_nSPV.h b/src/komodo_nSPV.h index 91c6ba7f4..fd90df5f4 100644 --- a/src/komodo_nSPV.h +++ b/src/komodo_nSPV.h @@ -37,6 +37,8 @@ #define NSPV_TXPROOFRESP 0x09 #define NSPV_SPENTINFO 0x0a #define NSPV_SPENTINFORESP 0x0b +#define NSPV_BROADCAST 0x0c +#define NSPV_BROADCASTRESP 0x0d int32_t iguana_rwbuf(int32_t rwflag,uint8_t *serialized,uint16_t len,uint8_t *buf) { @@ -254,7 +256,7 @@ void NSPV_txproof_purge(struct NSPV_txproof *ptr) } } -struct NSPV_utxo +/*struct NSPV_utxo { struct NSPV_txproof T; int64_t satoshis,extradata; @@ -272,7 +274,7 @@ int32_t NSPV_rwutxo(int32_t rwflag,uint8_t *serialized,struct NSPV_utxo *ptr) 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 { @@ -361,4 +363,24 @@ void NSPV_spentinfo_purge(struct NSPV_spentinfo *ptr) } } +struct NSPV_broadcastresp +{ + uint256 txid; + int32_t retcode; +}; + +int32_t NSPV_rwbroadcastresp(int32_t rwflag,uint8_t *serialized,struct NSPV_broadcastresp *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->retcode),&ptr->retcode); + return(len); +} + +void NSPV_broadcast_purge(struct NSPV_broadcastresp *ptr) +{ + if ( ptr != 0 ) + memset(ptr,0,sizeof(*ptr)); +} + #endif // KOMODO_NSPV_H diff --git a/src/komodo_nSPV_fullnode.h b/src/komodo_nSPV_fullnode.h index 6982e619e..49259f13f 100644 --- a/src/komodo_nSPV_fullnode.h +++ b/src/komodo_nSPV_fullnode.h @@ -195,6 +195,26 @@ uint8_t *NSPV_getrawtx(uint256 &hashBlock,uint16_t *txlenp,uint256 txid) return(rawtx); } +int32_t NSPV_sendrawtransaction(struct NSPV_broadcastresp *ptr,uint8_t *tx,int32_t n) +{ + CTransaction tx; std::string rawtx; + ptr->retcode = 0; + rawtx.resize(n*2+1); + init_hexbytes_noT(rawtx.data(),tx,n); + fprintf(stderr,"rawtx.(%s)\n",rawtx.c_str()); + if ( DecodeHexTx(tx,rawtx) != 0 ) + { + ptr->txid = tx.GetHash(); + if ( myAddtomempool(tx) != 0 ) + { + fprintf(stderr,"relay transaction %s\n",ptr->txid.GetHex().c_str()); + RelayTransaction(tx); + ptr->retcode = 1; + } else ptr->retcode = 0; + } else ptr->retcode = -1; + return(sizeof(*ptr)); +} + int32_t NSPV_gettxproof(struct NSPV_txproof *ptr,uint256 txid,int32_t height) { int32_t flag = 0,len = 0; uint256 hashBlock; CBlock block; CBlockIndex *pindex; @@ -458,7 +478,32 @@ void komodo_nSPVreq(CNode *pfrom,std::vector request) // received a req } } } - } + else if ( request[0] == NSPV_BROADCAST ) + { + if ( timestamp > pfrom->prevtimes[ind] ) + { + struct NSPV_broadcastresp B; uint16_t n,offset; uint256 txid; + if ( len > 1+sizeof(txid)+sizeof(n) ) + { + iguana_rwbignum(0,&request[1],sizeof(txid),(uint8_t *)&txid); + iguana_rwnum(0,&request[1+sizeof(txid)],sizeof(n),&n); + memset(&B,0,sizeof(B)); + offset = 1 + sizeof(txid) + sizeof(n); + if ( request.size() == offset+n && (slen= NSPV_sendrawtransaction(&B,&request[offset],n)) > 0 ) + { + response.resize(1 + slen); + response[0] = NSPV_BROADCASTRESP; + if ( NSPV_rwbroadcastresp(1,&response[1],&B) == slen ) + { + pfrom->PushMessage("nSPV",response); + pfrom->prevtimes[ind] = timestamp; + } + NSPV_broadcast_purge(&S); + } + } + } + } + } } #endif // KOMODO_NSPVFULLNODE_H diff --git a/src/komodo_nSPV_superlite.h b/src/komodo_nSPV_superlite.h index 982e751cf..482a0f330 100644 --- a/src/komodo_nSPV_superlite.h +++ b/src/komodo_nSPV_superlite.h @@ -41,7 +41,7 @@ struct NSPV_spentinfo NSPV_spentresult; struct NSPV_ntzsresp NSPV_ntzsresult; struct NSPV_ntzsproofresp NSPV_ntzsproofresult; struct NSPV_txproof NSPV_txproofresult; -struct NSPV_utxo *NSPV_utxos; +struct NSPV_broadcastresp NSPV_broadcastresult; CNode *NSPV_req(CNode *pnode,uint8_t *msg,int32_t len,uint64_t mask,int32_t ind) { @@ -192,6 +192,15 @@ UniValue NSPV_ntzsproof_json(struct NSPV_ntzsproofresp *ptr) return(result); } +UniValue NSPV_broadcast_json(struct NSPV_broadcastresp *ptr) +{ + UniValue result(UniValue::VOBJ); + result.push_back(Pair("result","success")); + result.push_back(Pair("txid",ptr->txid.GetHex())); + result.push_back(Pair("retcode",(int64_t)ptr->retcode)); + return(result); +} + UniValue NSPV_login(char *wifstr) { UniValue result(UniValue::VOBJ); char coinaddr[64]; uint8_t data[128]; int32_t len,valid = 0; @@ -364,6 +373,31 @@ UniValue NSPV_spentinfo(uint256 txid,int32_t vout) return(NSPV_spentinfo_json(&I)); } +UniValue NSPV_broadcast(char *hex) +{ + uint8_t msg[64],*tx; bits256 _txid; uint256 txid; uint16_t n; int32_t i,len = 0; struct NSPV_broadcastresult B; + n = (int32_t)strlen(hex) >> 1; + tx = malloc(n); + decode_hex(tx,n,hex); + _txid = bits256_doublesha256(0,tx,n); + memcpy(&txid,_txid,sizeof(txid)); + msg[len++] = NSPV_BROADCAST; + len += iguana_rwbignum(1,&msg[len],sizeof(txid),(uint8_t *)&txid); + len += iguana_rwnum(1,&msg[len],sizeof(n),&n); + memcpy(&msg[len],tx,n), len += n; + if ( NSPV_req(0,msg,len,NODE_NSPV,msg[0]>>1) != 0 ) + { + for (i=0; i response) // received a response { int32_t len; uint32_t timestamp = (uint32_t)time(NULL); @@ -384,25 +418,29 @@ void komodo_nSPVresp(CNode *pfrom,std::vector response) // received a r case NSPV_NTZSRESP: NSPV_ntzsresp_purge(&NSPV_ntzsresult); NSPV_rwntzsresp(0,&response[1],&NSPV_ntzsresult); - fprintf(stderr,"got ntzs response %u size.%d\n",timestamp,(int32_t)response.size()); // update utxos[i] + fprintf(stderr,"got ntzs response %u size.%d\n",timestamp,(int32_t)response.size()); break; case NSPV_NTZSPROOFRESP: NSPV_ntzsproofresp_purge(&NSPV_ntzsproofresult); NSPV_rwntzsproofresp(0,&response[1],&NSPV_ntzsproofresult); - fprintf(stderr,"got ntzproof response %u size.%d prev.%d next.%d\n",timestamp,(int32_t)response.size(),NSPV_ntzsproofresult.common.prevht,NSPV_ntzsproofresult.common.nextht); // update utxos[i] + fprintf(stderr,"got ntzproof response %u size.%d prev.%d next.%d\n",timestamp,(int32_t)response.size(),NSPV_ntzsproofresult.common.prevht,NSPV_ntzsproofresult.common.nextht); break; case NSPV_TXPROOFRESP: NSPV_txproof_purge(&NSPV_txproofresult); NSPV_rwtxproof(0,&response[1],&NSPV_txproofresult); - fprintf(stderr,"got txproof response %u size.%d\n",timestamp,(int32_t)response.size()); // update utxos[i] + fprintf(stderr,"got txproof response %u size.%d\n",timestamp,(int32_t)response.size()); break; case NSPV_SPENTINFORESP: - NSPV_spentinfo_purge(&NSPV_spentresult); NSPV_rwspentinfo(0,&response[1],&NSPV_spentresult); - fprintf(stderr,"got spentinfo response %u size.%d\n",timestamp,(int32_t)response.size()); // update utxos[i] + fprintf(stderr,"got spentinfo response %u size.%d\n",timestamp,(int32_t)response.size()); break; - default: fprintf(stderr,"unexpected response %02x size.%d at %u\n",response[0],(int32_t)response.size(),timestamp); + case NSPV_BROADCASTRESP: + NSPV_broadcast_purge(&NSPV_broadcastresult); + NSPV_rwbroadcast(0,&response[1],&NSPV_broadcastresult); + fprintf(stderr,"got broadcast response %u size.%d\n",timestamp,(int32_t)response.size()); + break; + default: fprintf(stderr,"unexpected response %02x size.%d at %u\n",response[0],(int32_t)response.size(),timestamp); break; } } diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp index 1d5cb83f1..36e4a8fda 100644 --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -425,6 +425,7 @@ static const CRPCCommand vRPCCommands[] = { "nSPV", "nspv_hdrsproof", &nspv_hdrsproof, true }, { "nSPV", "nspv_txproof", &nspv_txproof, true }, { "nSPV", "nspv_spend", &nspv_spend, true }, + { "nSPV", "nspv_broadcast", &nspv_broadcast, true }, // rewards { "rewards", "rewardslist", &rewardslist, true }, diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index c35b54965..225d32c80 100644 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -975,6 +975,7 @@ UniValue z_exportviewingkey(const UniValue& params, bool fHelp) UniValue NSPV_getinfo_json(); UniValue NSPV_login(char *wifstr); UniValue NSPV_addressutxos(char *coinaddr); +UniValue NSPV_broadcast(char *hex); UniValue NSPV_spend(char *srcaddr,char *destaddr,int64_t satoshis); UniValue NSPV_spentinfo(uint256 txid,int32_t vout); UniValue NSPV_notarizations(int32_t height); @@ -1058,3 +1059,9 @@ UniValue nspv_spend(const UniValue& params, bool fHelp) return(NSPV_spend((char *)NSPV_address.c_str(),(char *)params[0].get_str().c_str(),satoshis)); } +UniValue nspv_broadcast(const UniValue& params, bool fHelp) +{ + if ( fHelp || params.size() != 1 ) + throw runtime_error("nspv_broadcast hex\n"); + return(NSPV_broadcast((char *)params[0].get_str().c_str())); +}