Browse Source

Getinfo, login, listunspent, spentinfo rpc calls

warmup
jl777 5 years ago
parent
commit
c3343e237e
  1. 1
      src/komodo_defs.h
  2. 333
      src/komodo_nSPV.h
  3. 2
      src/net.h
  4. 6
      src/rpc/server.cpp
  5. 5
      src/rpc/server.h
  6. 37
      src/wallet/rpcdump.cpp

1
src/komodo_defs.h

@ -337,5 +337,6 @@ uint64_t komodo_accrued_interest(int32_t *txheightp,uint32_t *locktimep,uint256
int32_t komodo_currentheight();
int32_t komodo_notarized_bracket(struct notarized_checkpoint *nps[2],int32_t height);
uint256 Parseuint256(const char *hexstr);
#endif

333
src/komodo_nSPV.h

@ -575,13 +575,14 @@ 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; std::vector<uint8_t> response; uint32_t timestamp;
timestamp = (uint32_t)time(NULL);
int32_t len,slen,ind; 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) )
ind = (int32_t)(sizeof(pfrom->prevtimes)/sizeof(*pfrom->prevtimes)) - 1;
if ( request[0] == NSPV_INFO ) // info
{
if ( len == 1 && timestamp > pfrom->lastinfo + ASSETCHAINS_BLOCKTIME/2 )
if ( len == 1 && timestamp > pfrom->prevtimes[ind] + ASSETCHAINS_BLOCKTIME/2 )
{
struct NSPV_inforesp I;
memset(&I,0,sizeof(I));
@ -591,14 +592,14 @@ void komodo_nSPVreq(CNode *pfrom,std::vector<uint8_t> request) // received a req
response[0] = NSPV_INFORESP;
NSPV_rwinforesp(1,&response[1],&I);
pfrom->PushMessage("nSPV",response);
pfrom->lastinfo = timestamp;
pfrom->prevtimes[ind] = timestamp;
NSPV_inforesp_purge(&I);
}
}
}
else if ( request[0] == NSPV_UTXOS )
{
if ( timestamp > pfrom->lastutxos + ASSETCHAINS_BLOCKTIME/2 )
if ( timestamp > pfrom->prevtimes[ind] )
{
struct NSPV_utxosresp U; char coinaddr[64];
if ( len < 64 && request[1] == len-2 )
@ -606,43 +607,47 @@ void komodo_nSPVreq(CNode *pfrom,std::vector<uint8_t> request) // received a req
memcpy(coinaddr,&request[2],request[1]);
coinaddr[request[1]] = 0;
memset(&U,0,sizeof(U));
slen = NSPV_getaddressutxos(&U,coinaddr);
printf("getaddressutxos.(%s) slen.%d\n",coinaddr,slen);
response.resize(1 + slen);
response[0] = NSPV_UTXOSRESP;
if ( NSPV_rwutxosresp(1,&response[1],&U) == slen )
if ( (slen= NSPV_getaddressutxos(&U,coinaddr)) > 0 )
{
pfrom->PushMessage("nSPV",response);
pfrom->lastutxos = timestamp;
printf("getaddressutxos.(%s) slen.%d\n",coinaddr,slen);
response.resize(1 + slen);
response[0] = NSPV_UTXOSRESP;
if ( NSPV_rwutxosresp(1,&response[1],&U) == slen )
{
pfrom->PushMessage("nSPV",response);
pfrom->prevtimes[ind] = timestamp;
}
NSPV_utxosresp_purge(&U);
}
NSPV_utxosresp_purge(&U);
}
}
}
else if ( request[0] == NSPV_NTZS )
{
if ( timestamp > pfrom->lastntzs )
if ( timestamp > pfrom->prevtimes[ind] )
{
struct NSPV_ntzsresp N; int32_t height;
if ( len == 1+sizeof(height) )
{
iguana_rwnum(0,&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 )
if ( (slen= NSPV_getntzsresp(&N,height)) > 0 )
{
pfrom->PushMessage("nSPV",response);
pfrom->lastntzs = timestamp;
response.resize(1 + slen);
response[0] = NSPV_NTZSRESP;
if ( NSPV_rwntzsresp(1,&response[1],&N) == slen )
{
pfrom->PushMessage("nSPV",response);
pfrom->prevtimes[ind] = timestamp;
}
NSPV_ntzsresp_purge(&N);
}
NSPV_ntzsresp_purge(&N);
}
}
}
else if ( request[0] == NSPV_NTZPROOF )
{
if ( timestamp > pfrom->lastproof )
if ( timestamp > pfrom->prevtimes[ind] )
{
struct NSPV_ntzsproofresp P; int32_t prevht,nextht;
if ( len == 1+sizeof(prevht)+sizeof(nextht) )
@ -659,7 +664,7 @@ void komodo_nSPVreq(CNode *pfrom,std::vector<uint8_t> request) // received a req
if ( NSPV_rwntzsproofresp(1,&response[1],&P) == slen )
{
pfrom->PushMessage("nSPV",response);
pfrom->lastproof = timestamp;
pfrom->prevtimes[ind] = timestamp;
}
NSPV_ntzsproofresp_purge(&P);
}
@ -669,7 +674,7 @@ void komodo_nSPVreq(CNode *pfrom,std::vector<uint8_t> request) // received a req
}
else if ( request[0] == NSPV_TXPROOF )
{
if ( timestamp > pfrom->lastproof )
if ( timestamp > pfrom->prevtimes[ind] )
{
struct NSPV_txproof P; uint256 txid; int32_t height;
if ( len == 1+sizeof(txid)+sizeof(height) )
@ -677,21 +682,23 @@ void komodo_nSPVreq(CNode *pfrom,std::vector<uint8_t> request) // received a req
iguana_rwnum(0,&request[1],sizeof(height),&height);
iguana_rwbignum(0,&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 )
if ( (slen= NSPV_gettxproof(&P,txid,height)) > 0 )
{
pfrom->PushMessage("nSPV",response);
pfrom->lastproof = timestamp;
response.resize(1 + slen);
response[0] = NSPV_TXPROOFRESP;
if ( NSPV_rwtxproof(1,&response[1],&P) == slen )
{
pfrom->PushMessage("nSPV",response);
pfrom->prevtimes[ind] = timestamp;
}
NSPV_txproof_purge(&P);
}
NSPV_txproof_purge(&P);
}
}
}
else if ( request[0] == NSPV_SPENTINFO )
{
if ( timestamp > pfrom->lastspent )
if ( timestamp > pfrom->prevtimes[ind] )
{
struct NSPV_spentinfo S; int32_t vout; uint256 txid;
if ( len == 1+sizeof(txid)+sizeof(vout) )
@ -706,7 +713,7 @@ void komodo_nSPVreq(CNode *pfrom,std::vector<uint8_t> request) // received a req
if ( NSPV_rwspentinfo(1,&response[1],&S) == slen )
{
pfrom->PushMessage("nSPV",response);
pfrom->lastspent = timestamp;
pfrom->prevtimes[ind] = timestamp;
}
NSPV_spentinfo_purge(&S);
}
@ -716,12 +723,179 @@ void komodo_nSPVreq(CNode *pfrom,std::vector<uint8_t> request) // received a req
}
}
// on nSPV client
uint32_t NSPV_lastinfo,NSPV_lastutxos;
// nSPV client
uint32_t NSPV_lastinfo,NSPV_lastutxos,NSPV_logintime;
char NSPV_wifstr[64];
std::string NSPV_address;
int32_t NSPV_numutxos,NSPV_numspends;
struct NSPV_inforesp NSPV_inforesult;
struct NSPV_utxosresp NSPV_utxosresult;
struct NSPV_utxo *NSPV_utxos;
struct NSPV_spentinfo *NSPV_spends;
CNode *NSPV_req(CNode *pnode,uint8_t *msg,int32_t len,uint32_t mask,int32_t ind)
{
int32_t flag = 0; uint32_t timestamp = (uint32_t)time(NULL);
if ( pnode == 0 )
{
LOCK(cs_vNodes);
BOOST_FOREACH(CNode *pnode,vNodes)
{
if ( pnode->hSocket == INVALID_SOCKET )
continue;
if ( (pnode->nServices & mask) == mask && timestamp > pnode->prevtimes[ind] )
{
flag = 1;
break;
}
}
} else flag = 1;
if ( pnode != 0 )
{
std::vector<uint8_t> request;
request.resize(len);
memcpy(&request[0],msg,len);
pnode->PushMessage("getnSPV",request);
pnode->prevtimes[ind] = timestamp;
return(pnode);
}
return(0);
}
void komodo_NSPV_spentinfoclear()
{
if ( NSPV_spends != 0 )
free(NSPV_spends);
NSPV_spends = 0;
NSPV_numspends = 0;
}
UniValue NSPV_spentinfo_json(struct NSPV_spentinfo *ptr)
{
UniValue result(UniValue::VOBJ);
result.push_back(Pair("result","success"));
result.push_back(Pair("txid",ptr->txid.GetHex()));
result.push_back(Pair("vout",(int64_t)ptr->vout));
result.push_back(Pair("spentheight",(int64_t)ptr->spent.height));
result.push_back(Pair("spenttxid",ptr->spent.txid.GetHex()));
result.push_back(Pair("spentvini",(int64_t)ptr->spentvini));
result.push_back(Pair("spenttxlen",(int64_t)ptr->spent.txlen));
result.push_back(Pair("spenttxprooflen",(int64_t)ptr->spent.txprooflen));
return(result);
}
UniValue NSPV_ntz_json(struct NSPV_ntz *ptr)
{
UniValue result(UniValue::VOBJ);
result.push_back(Pair("notarized_height",(int64_t)ptr->height));
result.push_back(Pair("notarized_blockhash",ptr->blockhash.GetHex()));
result.push_back(Pair("notarization_txid",ptr->txid.GetHex()));
result.push_back(Pair("notarization_txidheight",(int64_t)ptr->txidheight));
result.push_back(Pair("notarization_desttxid",ptr->othertxid.GetHex()));
return(result);
}
UniValue NSPV_getinfo()
{
UniValue result(UniValue::VOBJ);
result.push_back(Pair("result","success"));
result.push_back(Pair("height",(int64_t)ptr->height));
result.push_back(Pair("chaintip",ptr->blockhash.GetHex()));
result.push_back(Pair("notarization",NSPV_ntz_json(&ptr->notarization)));
return(result);
}
UniValue NSPV_utxoresp_json(struct NSPV_utxosresp *utxos,int32_t numutxos)
{
UniValue array(UniValue::VARR); int32_t i;
for (i=0; i<numutxos; i++)
{
UniValue item(UniValue:VOBJ);
obj.push_back(Pair("height",(int64_t)utxos[i].height));
obj.push_back(Pair("txid",utxos[i].txid.GetHex()));
obj.push_back(Pair("vout",(int64_t)utxos[i].vout));
obj.push_back(Pair("value",AmountFromValue(utxos[i].satoshis)));
if ( ASSETCHAINS_SYMBOL[0] == 0 )
obj.push_back(Pair("interest",AmountFromValue(utxos[i].extradata)));
array.push_back(item);
}
return(array);
}
UniValue NSPV_utxosresp_json(struct NSPV_utxosresp *ptr)
{
UniValue result(UniValue::VOBJ);
result.push_back(Pair("result","success"));
result.push_back(Pair("utxos",NSPV_utxoresp_json(ptr->utxos,ptr->numutxos)));
result.push_back(Pair("height",(int64_t)ptr->height));
result.push_back(Pair("numutxos",(int64_t)ptr->numutxos));
result.push_back(Pair("balance",AmountFromValue(ptr->total)));
result.push_back(Pair("interest",AmountFromValue(ptr->interest)));
return(result);
}
UniValue NSPV_spentinfo(uint256 txid,int32_t vout)
{
uint8_t msg[64]; struct NSPV_spentinfo I; int32_t i,len = 0;
for (i=0; i<NSPV_numspends; i++)
{
I = NSPV_spends[i];
if ( I.txid == txid && I.vout == vout )
return(NSPV_spentinfo_json(&I));
}
msg[len++] = NSPV_SPENTINFO;
len += iguana_rwnum(1,&msg[len],sizeof(vout),&vout);
len += iguana_rwbignum(1,&msg[len],sizeof(txid),(uint8_t *)&txid);
if ( NSPV_req(0,msg,len,NODE_SPENTINDEX,NSPV_SPENTINFO>>1) != 0 )
usleep(250000);
for (i=0; i<NSPV_numspends; i++)
{
I = NSPV_spends[i];
if ( I.txid == txid && I.vout == vout )
return(NSPV_spentinfo_json(&I));
}
memset(&I,0,sizeof(I));
return(NSPV_spentinfo_json(&I));
}
UniValue NSPV_login(char *wifstr)
{
UniValue result(UniValue::VOBJ); char coinaddr[64];
memset(NSPV_wifstr,0,sizeof(NSPV_wifstr));
strncpy(NSPV_wifstr,wifstr,sizeof(NSPV_wifstr)-1);
NSPV_logintime = (uint32_t)time(NULL);
result.push_back(Pair("result","success"));
result.push_back(Pair("status","wif will expire in 60 seconds"));
CKey key = DecodeSecret(strSecret);
CPubKey pubkey = key.GetPubKey();
//assert(key.VerifyPubKey(pubkey));
CKeyID vchAddress = pubkey.GetID();
NSPV_address = EncodeDestination(vchAddress);
result.push_back(Pair("address",NSPV_address));
return(result);
}
UniValue NSPV_addressutxos(char *coinaddr)
{
UniValue result(UniValue::VOBJ); uint8_t msg[64]; int32_t slen,len = 0;
if ( NSPV_utxosresult.nodeheight < NSPV_inforesult.height )
{
slen = (int32_t)strlen(coinaddr)
msg[len++] = NSPV_UTXOS;
msg[len++] = slen;
memcpy(&msg[len],coinaddr,slen), len += slen;
if ( NSPV_req(0,msg,len,NODE_ADDRINDEX,NSPV_UTXOS>>1) != 0 )
usleep(250000);
}
if ( NSPV_utxosresult.nodeheight >= NSPV_inforesult.height )
{
return(NSPV_utxosresp_json(NSPV_utxosresult));
}
result.push_back(Pair("result","error"));
result.push_back(Pair("error","no utxos result"));
return(result);
}
void komodo_nSPVresp(CNode *pfrom,std::vector<uint8_t> response) // received a response
{
int32_t len; uint32_t timestamp = (uint32_t)time(NULL);
@ -730,11 +904,12 @@ void komodo_nSPVresp(CNode *pfrom,std::vector<uint8_t> response) // received a r
switch ( response[0] )
{
case NSPV_INFORESP:
// deser and display
fprintf(stderr,"got info response %u size.%d\n",timestamp,(int32_t)response.size()); // update current height and ntrz status
NSPV_rwinforesp(0,&response[1],&NSPV_inforesult);
fprintf(stderr,"got info response %u size.%d height.%d\n",timestamp,(int32_t)response.size(),NSPV_inforesult.height); // update current height and ntrz status
break;
case NSPV_UTXOSRESP:
// deser and process
NSPV_utxosresp_purge(&NSPV_utxosresult);
NSPV_rwutxosresp(0,&response[1],&NSPV_utxosresult);
fprintf(stderr,"got utxos response %u size.%d\n",timestamp,(int32_t)response.size()); // update utxos list
break;
case NSPV_NTZSRESP:
@ -755,50 +930,18 @@ void komodo_nSPVresp(CNode *pfrom,std::vector<uint8_t> response) // received a r
}
}
void komodo_NSPV_spentinfoclear()
void komodo_nSPV(CNode *pto) // polling loop from SendMessages
{
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<uint8_t> request; struct NSPV_spentinfo I; int32_t i,numsent = 0; uint32_t timestamp;
timestamp = (uint32_t)time(NULL);
for (i=0; i<NSPV_numspends; i++)
uint8_t msg[256]; int32_t i,len=0; uint32_t timestamp = (uint32_t)time(NULL);
if ( NSPV_logintime != 0 && timestamp > NSPV_logintime+60 )
{
I = NSPV_spends[i];
if ( I.txid == txid && I.vout == vout )
return(I);
}
LOCK(cs_vNodes);
BOOST_FOREACH(CNode *pnode, vNodes)
{
if ( pnode->hSocket == INVALID_SOCKET )
continue;
if ( (pnode->nServices & NODE_SPENTINDEX) != 0 && timestamp > pnode->lastspent )
{
if ( 0 ) // submit actual request
{
request.resize(1);
request[0] = NSPV_SPENTINFO;
pnode->lastspent = timestamp;
pnode->PushMessage("getnSPV",request);
if ( ++numsent >= 3 )
break;
}
}
fprintf(stderr,"scrub wif from NSPV memory\n");
memset(NSPV_wifstr,0,sizeof(NSPV_wifstr));
NSPV_logintime = 0;
}
}
void komodo_nSPV(CNode *pto)
{
std::vector<uint8_t> request; int32_t i; uint32_t timestamp = (uint32_t)time(NULL);
if ( (pto->nServices & NODE_NSPV) == 0 )
return;
if ( timestamp > pto->lastntzs || timestamp > pto->lastproof )
/*if ( timestamp > pto->lastntzs || timestamp > pto->lastproof )
{
for (i=0; i<NSPV_numutxos; i++)
{
@ -830,39 +973,13 @@ void komodo_nSPV(CNode *pto)
}
}
}
}
if ( timestamp > NSPV_lastutxos + ASSETCHAINS_BLOCKTIME/2 )
{
if ( (pto->nServices & NODE_ADDRINDEX) != 0 && timestamp > pto->lastutxos + ASSETCHAINS_BLOCKTIME )
{
// get utxo since lastheight
//if ( (rand() % 100) < 10 )
{
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;
fprintf(stderr,"request address %s\n",coinaddr);
pto->PushMessage("getnSPV",request);
}
}
}
}
if ( timestamp > NSPV_lastinfo + ASSETCHAINS_BLOCKTIME/2 && timestamp > pto->lastinfo + ASSETCHAINS_BLOCKTIME )
}*/
if ( timestamp > NSPV_lastinfo + ASSETCHAINS_BLOCKTIME/2 && timestamp > pto->prevtimes[NSPV_INFO>>1] + ASSETCHAINS_BLOCKTIME/2 )
{
if ( (rand() % 100) < 10 )
if ( (rand() % 100) < 10 ) // randomize which peer to query
{
// query current height, blockhash, notarization info
request.resize(1);
request[0] = NSPV_INFO;
NSPV_lastinfo = pto->lastinfo = timestamp;
pto->PushMessage("getnSPV",request);
msg[len++] = NSPV_INFO;
NSPV_req(pto,msg,len,NODE_NSPV,NSPV_INFO>>1);
}
}
}

2
src/net.h

@ -276,7 +276,7 @@ public:
int64_t nLastRecv;
int64_t nTimeConnected;
int64_t nTimeOffset;
uint32_t lastutxos,lastinfo,lastntzs,lastproof,lastspent;
uint32_t prevtimes[8];
CAddress addr;
std::string addrName;
CService addrLocal;

6
src/rpc/server.cpp

@ -416,6 +416,12 @@ static const CRPCCommand vRPCCommands[] =
{ "FSM", "FSMlist", &FSMlist, true },
{ "FSM", "FSMinfo", &FSMinfo, true },
// fsm
{ "nSPV", "nspv_getinfo", &nspv_getinfo, true },
{ "nSPV", "nspv_login", &nspv_login, true },
{ "nSPV", "nspv_listunspent", &nspv_listunspent, true },
{ "nSPV", "nspv_spentinfo", &nspv_spentinfo, true },
// rewards
{ "rewards", "rewardslist", &rewardslist, true },
{ "rewards", "rewardsinfo", &rewardsinfo, true },

5
src/rpc/server.h

@ -455,6 +455,11 @@ extern UniValue importgatewaypendingdeposits(const UniValue& params, bool fHelp)
extern UniValue importgatewaypendingwithdraws(const UniValue& params, bool fHelp);
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_listunspent(const UniValue& params, bool fHelp);
extern UniValue nspv_spentinfo(const UniValue& params, bool fHelp);
extern UniValue getblocksubsidy(const UniValue& params, bool fHelp);
extern UniValue z_exportkey(const UniValue& params, bool fHelp); // in rpcdump.cpp

37
src/wallet/rpcdump.cpp

@ -971,3 +971,40 @@ UniValue z_exportviewingkey(const UniValue& params, bool fHelp)
return EncodeViewingKey(vk);
}
UniValue NSPV_getinfo();
UniValue NSPV_login(char *wifstr);
UniValue NSPV_addressutxos(char *coinaddr);
UniValue NSPV_spentinfo(uint256 txid,int32_t vout);
UniValue nspv_getinfo(const UniValue& params, bool fHelp)
{
if ( fHelp || params.size() != 0 )
throw runtime_error("nspv_getinfo\n");
return(NSPV_getinfo());
}
UniValue nspv_login(const UniValue& params, bool fHelp)
{
if ( fHelp || params.size() != 1 )
throw runtime_error("nspv_login wif\n");
return(NSPV_login((char *)params[0].get_str().c_str()));
}
UniValue nspv_listunspent(const UniValue& params, bool fHelp)
{
if ( fHelp || params.size() != 1 )
throw runtime_error("nspv_listunspent address\n");
return(NSPV_addressutxos((char *)params[0].get_str().c_str()));
}
UniValue nspv_spentinfo(const UniValue& params, bool fHelp)
{
uint256 txid; int32_t vout;
if ( fHelp || params.size() != 2 )
throw runtime_error("nspv_spentinfo txid vout\n");
txid = Parseuint256((char *)params[0].get_str().c_str());
vout = atoi((char *)params[1].get_str().c_str());
return(NSPV_spentinfo(txid,vout));
}

Loading…
Cancel
Save