From 429dabb503382ce119b6a7eeda9266c882e11013 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 27 Oct 2016 09:49:42 -0300 Subject: [PATCH] test --- src/komodo.h | 38 +++++++---- src/komodo_gateway.h | 151 +++++++++++++++++++++++++++++++++++------- src/komodo_notary.h | 2 +- src/komodo_pax.h | 3 +- src/komodo_utils.h | 117 +++++++++++++++++++++++++++++++- src/tinyformat.h | 2 +- src/wallet/wallet.cpp | 3 +- 7 files changed, 272 insertions(+), 44 deletions(-) diff --git a/src/komodo.h b/src/komodo.h index d4b6932ce..3e0e43a44 100644 --- a/src/komodo.h +++ b/src/komodo.h @@ -23,18 +23,20 @@ #include #include -void komodo_stateupdate(int32_t height,uint8_t notarypubs[][33],uint8_t numnotaries,uint8_t notaryid,uint256 txhash,uint64_t voutmask,uint8_t numvouts,uint32_t *pvals,uint8_t numpvals,int32_t kheight,uint64_t opretvalue,uint8_t *opretbuf,uint16_t opretlen); +void komodo_stateupdate(int32_t height,uint8_t notarypubs[][33],uint8_t numnotaries,uint8_t notaryid,uint256 txhash,uint64_t voutmask,uint8_t numvouts,uint32_t *pvals,uint8_t numpvals,int32_t kheight,uint64_t opretvalue,uint8_t *opretbuf,uint16_t opretlen,uint16_t vout); void komodo_init(); int32_t komodo_notarizeddata(int32_t nHeight,uint256 *notarized_hashp,uint256 *notarized_desttxidp); char *komodo_issuemethod(char *method,char *params,uint16_t port); -int32_t NOTARIZED_HEIGHT,Num_nutxos,KMDHEIGHT = 40000; +int32_t ASSETCHAINS_SHORTFLAG,NOTARIZED_HEIGHT,Num_nutxos,KMDHEIGHT = 40000; uint256 NOTARIZED_HASH,NOTARIZED_DESTTXID; pthread_mutex_t komodo_mutex; char KMDUSERPASS[1024]; uint16_t BITCOIND_PORT = 7771; -uint64_t KOMODO_DEPOSIT; uint8_t KOMODO_SCRIPTPUBKEY[25]; +uint64_t KOMODO_DEPOSIT,PENDING_KOMODO_TX; #include "komodo_utils.h" +queue_t DepositsQ,PendingsQ; + #include "cJSON.c" #include "komodo_bitcoind.h" #include "komodo_interest.h" @@ -43,7 +45,7 @@ uint64_t KOMODO_DEPOSIT; uint8_t KOMODO_SCRIPTPUBKEY[25]; #include "komodo_gateway.h" -void komodo_stateupdate(int32_t height,uint8_t notarypubs[][33],uint8_t numnotaries,uint8_t notaryid,uint256 txhash,uint64_t voutmask,uint8_t numvouts,uint32_t *pvals,uint8_t numpvals,int32_t KMDheight,uint64_t opretvalue,uint8_t *opretbuf,uint16_t opretlen) +void komodo_stateupdate(int32_t height,uint8_t notarypubs[][33],uint8_t numnotaries,uint8_t notaryid,uint256 txhash,uint64_t voutmask,uint8_t numvouts,uint32_t *pvals,uint8_t numpvals,int32_t KMDheight,uint64_t opretvalue,uint8_t *opretbuf,uint16_t opretlen,uint16_t vout) { static FILE *fp; static int32_t errs; char fname[512]; int32_t ht,func; uint8_t num,pubkeys[64][33]; #ifdef WIN32 @@ -110,7 +112,11 @@ void komodo_stateupdate(int32_t height,uint8_t notarypubs[][33],uint8_t numnotar } else if ( func == 'R' ) { - uint16_t olen; uint64_t ovalue; uint8_t opret[10000]; + uint16_t olen,v; uint64_t ovalue; uint256 txid; uint8_t opret[10000]; + if ( fread(&txid,1,sizeof(txid),fp) != sizeof(txid) ) + errs++; + if ( fread(&v,1,sizeof(v),fp) != sizeof(v) ) + errs++; if ( fread(&ovalue,1,sizeof(ovalue),fp) != sizeof(ovalue) ) errs++; if ( fread(&olen,1,sizeof(olen),fp) != sizeof(olen) ) @@ -119,7 +125,7 @@ void komodo_stateupdate(int32_t height,uint8_t notarypubs[][33],uint8_t numnotar { if ( fread(opret,1,olen,fp) != olen ) errs++; - komodo_opreturn(ht,ovalue,opret,olen); + komodo_opreturn(ht,ovalue,opret,olen,txid,v); } else printf("illegal olen.%u\n",olen); } else if ( func == 'D' ) @@ -174,6 +180,10 @@ void komodo_stateupdate(int32_t height,uint8_t notarypubs[][33],uint8_t numnotar fputc('R',fp); if ( fwrite(&height,1,sizeof(height),fp) != sizeof(height) ) errs++; + if ( fwrite(&txhash,1,sizeof(txhash),fp) != sizeof(txhash) ) + errs++; + if ( fwrite(&vout,1,sizeof(vout),fp) != sizeof(vout) ) + errs++; if ( fwrite(&opretvalue,1,sizeof(opretvalue),fp) != sizeof(opretvalue) ) errs++; if ( fwrite(&olen,1,sizeof(olen),fp) != olen ) @@ -181,7 +191,7 @@ void komodo_stateupdate(int32_t height,uint8_t notarypubs[][33],uint8_t numnotar if ( fwrite(opretbuf,1,olen,fp) != olen ) errs++; //printf("ht.%d R opret[%d]\n",height,olen); - komodo_opreturn(height,opretvalue,opretbuf,olen); + komodo_opreturn(height,opretvalue,opretbuf,olen,txhash,numvouts); } else if ( notarypubs != 0 && numnotaries > 0 ) { @@ -293,9 +303,9 @@ int32_t komodo_voutupdate(int32_t notaryid,uint8_t *scriptbuf,int32_t scriptlen, opretlen = scriptbuf[len++]; opretlen = (opretlen << 8) + scriptbuf[len++]; } - for (k=0; k= 32*2+4 && strcmp(KOMODO_SOURCE,(char *)&scriptbuf[len+32*2+4]) == 0 ) { len += iguana_rwbignum(0,&scriptbuf[len],32,(uint8_t *)&kmdtxid); @@ -307,12 +317,12 @@ int32_t komodo_voutupdate(int32_t notaryid,uint8_t *scriptbuf,int32_t scriptlen, NOTARIZED_HEIGHT = *notarizedheightp; NOTARIZED_HASH = kmdtxid; NOTARIZED_DESTTXID = desttxid; - komodo_stateupdate(height,0,0,0,zero,0,0,0,0,0,0,0,0); + komodo_stateupdate(height,0,0,0,zero,0,0,0,0,0,0,0,0,0); } else printf("reject ht.%d NOTARIZED.%d %s.%s DESTTXID.%s (%s)\n",height,*notarizedheightp,KOMODO_SOURCE,kmdtxid.ToString().c_str(),desttxid.ToString().c_str(),(char *)&scriptbuf[len]); } else if ( i == 0 && j == 1 && opretlen == 149 ) komodo_paxpricefeed(height,&scriptbuf[len],opretlen); - else komodo_stateupdate(height,0,0,0,zero,0,0,0,0,0,value,&scriptbuf[len],opretlen); + else komodo_stateupdate(height,0,0,0,txhash,0,0,0,0,0,value,&scriptbuf[len],opretlen,j); } return(notaryid); } @@ -373,7 +383,7 @@ void komodo_connectblock(CBlockIndex *pindex,CBlock& block) } if ( i != 0 && notaryid >= 0 && notaryid < 64 && voutmask != 0 ) { - komodo_stateupdate(height,0,0,notaryid,txhash,voutmask,numvouts,0,0,0,0,0,0); + komodo_stateupdate(height,0,0,notaryid,txhash,voutmask,numvouts,0,0,0,0,0,0,0); //komodo_nutxoadd(height,notaryid,txhash,voutmask,numvouts); } signedmask = 0; @@ -414,7 +424,7 @@ void komodo_connectblock(CBlockIndex *pindex,CBlock& block) if ( komodo_isratify(1,numvalid) > 13 ) { memset(&txhash,0,sizeof(txhash)); - komodo_stateupdate(height,pubkeys,numvalid,0,txhash,0,0,0,0,0,0,0,0); + komodo_stateupdate(height,pubkeys,numvalid,0,txhash,0,0,0,0,0,0,0,0,0); } printf("new notaries.%d newheight.%d from height.%d\n",numvouts-1,KOMODO_PUBKEYS_HEIGHT(height),height); } diff --git a/src/komodo_gateway.h b/src/komodo_gateway.h index 7a4558139..c6386d3ad 100644 --- a/src/komodo_gateway.h +++ b/src/komodo_gateway.h @@ -13,13 +13,102 @@ * * ******************************************************************************/ -// create list of approved deposits, validate all deposits against this list, prevent double deposit -// need to tag deposits with OP_RETURN, ie link with originating txid/vout // paxdeposit equivalent in reverse makes opreturn and KMD does the same in reverse -const char *komodo_opreturn(int32_t height,uint64_t value,uint8_t *opretbuf,int32_t opretlen) +struct pax_transaction { - uint8_t rmd160[20],addrtype,shortflag,pubkey33[33]; int32_t i,tokomodo=0; char base[4],coinaddr[64],destaddr[64]; int64_t fiatoshis,checktoshis; const char *typestr = "unknown"; + struct queueitem DL; + uint256 txid; + uint64_t komodoshis,fiatoshis; + uint16_t vout; + char symbol[4]; uint8_t rmd160[20],shortflag; +}; + +void komodo_gateway_deposits(CMutableTransaction& txNew) +{ + struct pax_transaction *ptr; uint8_t *script,opret[10000],data[10000]; int32_t i,len=0,opretlen=0,numvouts=1; + PENDING_KOMODO_TX = 0; + while ( (ptr= queue_dequeue(&DepositQ,0)) != 0 ) + { + txNew.vout.resize(numvouts+1); + txNew.vout[numvouts].nValue = ptr->fiatoshis; + txNew.vout[numvouts].scriptPubKey.resize(25); + script = (uint8_t *)&txNew.vout[numvouts].scriptPubKey[0]; + *script++ = 0x76; + *script++ = 0xa9; + *script++ = 20; + memcpy(script,rmd160,20), script += 20; + *script++ = 0x88; + *script++ = 0xac; + for (i=0; i<32; i++) + { + printf("%02x",((uint8_t *)&ptr->txid)[i]); + data[len++] = ((uint8_t *)&ptr->txid)[i]; + } + data[len++] = ptr->vout & 0xff; + data[len++] = (ptr->vout >> 8) & 0xff; + printf(" vout.%u DEPOSIT %.8f\n",ptr->vout,(double)KOMODO_DEPOSIT/COIN); + PENDING_KOMODO_TX += ptr->fiatoshis; + numvouts++; + queue_enqueue("PENDINGS",&PendingsQ,&ptr->DL,0); + } + if ( numvouts > 1 ) + { + opretlen = komodo_opreturnscript(opret,'I',data,len); + txNew.vout.resize(numvouts+1); + txNew.vout[numvouts].nValue = 0; + txNew.vout[numvouts].scriptPubKey.resize(opretlen); + script = (uint8_t *)&txNew.vout[numvouts].scriptPubKey[0]; + memcpy(script,opret,opretlen); + } + printf("total numvouts.%d %.8f\n",numvouts,dstr(PENDING_KOMODO_TX)); +} + +void komodo_gateway_deposit(uint64_t value,int32_t shortflag,char *symbol,uint64_t fiatoshis,uint8_t *rmd160,uint256 txid,uint16_t vout) // assetchain context +{ + struct pax_transaction *ptr; + ptr = calloc(1,sizeof(*ptr)); + ptr->komodoshis = value; + ptr->fiatoshis = fiatoshis; + memcpy(ptr->symbol,symbol,3); + memcpy(ptr->rmd160,rmd160,20) + ptr->shortflag = shortflag; + ptr->txid = txid; + ptr->vout = vout; + KOMODO_DEPOSIT += fiatoshis; + queue_enqueue("DEPOSITS",&DepositsQ,&ptr->DL,0); +} + +void komodo_gateway_depositremove(uint256 txid,uint16_t vout) // assetchain context +{ + int32_t iter; queue_t *Q; + for (iter=0; iter<2; iter++) + { + Q = (iter == 0) ? &DepositsQ : &PendingsQ; + portable_mutex_lock(&Q->mutex); + if ( Q->list != 0 ) + { + DL_FOREACH(Q->list,ptr) + { + if ( memcmp(&ptr->txid,&txid,sizeof(txid)) == 0 && ptr->vout == vout ) + { + if ( KOMODO_DEPOSIT >= ptr->fiatoshis ) + KOMODO_DEPOSIT -= ptr->fiatoshis; + else KOMODO_DEPOSIT = 0; + printf("DELETE %.8f DEPOSIT %s %.8f\n",dstr(ptr->value),ptr->symbol,dstr(ptr->fiatoshis)); + DL_DELETE(Q->list,ptr); + myfree(ptr,sizeof(struct queueitem)); + break; + } + } + } + portable_mutex_unlock(&Q->mutex); + } +} + +const char *komodo_opreturn(int32_t height,uint64_t value,uint8_t *opretbuf,int32_t opretlen,uint256 txid,uint16_t vout) +{ + uint8_t rmd160[20],addrtype,shortflag,pubkey33[33]; int32_t i,j,len,tokomodo=0; char base[4],coinaddr[64],destaddr[64]; int64_t fiatoshis,checktoshis; const char *typestr = "unknown"; //printf("komodo_opreturn[%c]: ht.%d %.8f opretlen.%d\n",opretbuf[0],height,dstr(value),opretlen); #ifdef KOMODO_ISSUER tokomodo = 1; @@ -36,31 +125,49 @@ const char *komodo_opreturn(int32_t height,uint64_t value,uint8_t *opretbuf,int3 checktoshis = PAX_fiatdest(tokomodo,destaddr,pubkey33,coinaddr,height,base,fiatoshis); for (i=0; i %s\n",dstr(fiatoshis),shortflag!=0?'-':'+',base,coinaddr); - // verify price value for fiatoshis of base + printf(" DEPOSIT %.8f %c%s -> %s ",dstr(fiatoshis),shortflag!=0?'-':'+',base,coinaddr); + for (i=0; i<32; i++) + printf("%02x",((uint8_t *)&txid)[i]); + printf(" <- txid.v%u ",vout); for (i=0; i<33; i++) printf("%02x",pubkey33[i]); printf(" checkpubkey check %.8f v %.8f dest.(%s)\n",dstr(checktoshis),dstr(value),destaddr); typestr = "deposit"; #ifdef KOMODO_ISSUER - if ( strncmp(KOMODO_SOURCE,base,strlen(base)) == 0 && ((tokomodo == 0 && value >= checktoshis*.9999) || (tokomodo != 0 && value <= checktoshis/.9999)) ) + if ( strncmp(KOMODO_SOURCE,base,strlen(base)) == 0 && value >= (9999*checktoshis)/10000 && shortflag == ASSETCHAINS_SHORTFLAG ) { - printf("START %s MINER! %.8f\n",KOMODO_SOURCE,dstr(fiatoshis)); - KOMODO_DEPOSIT = fiatoshis; - KOMODO_SCRIPTPUBKEY[0] = 0x76; - KOMODO_SCRIPTPUBKEY[1] = 0xa9; - KOMODO_SCRIPTPUBKEY[2] = 0x14; - memcpy(&KOMODO_SCRIPTPUBKEY[3],rmd160,0x14); - KOMODO_SCRIPTPUBKEY[23] = 0x88; - KOMODO_SCRIPTPUBKEY[24] = 0xac; + komodo_gateway_deposit(value,shortflag,symbol,fiatoshis,rmd160,txid,vout); + } +#else + if ( tokomodo != 0 && value <= (10000*checktoshis)/9999 ) + { + } #endif } } + else if ( opretbuf[0] == 'I' ) + { + uint256 issuedtxid; uint16_t issuedvout; + opretbuf++, opretlen--; + for (i=len=0; i 13 ) typestr = "ratify"; @@ -92,7 +196,7 @@ void komodo_gateway_voutupdate(char *symbol,int32_t isspecial,int32_t height,int int32_t komodo_gateway_tx(char *symbol,int32_t height,int32_t txi,char *txidstr,uint32_t port) { - char *retstr,params[256],*hexstr; uint8_t script[10000]; cJSON *json,*result,*vouts,*item,*sobj; int32_t vout,n,len,isspecial,retval = -1; uint64_t value; + char *retstr,params[256],*hexstr; uint8_t script[10000]; cJSON *json,*result,*vouts,*item,*sobj; int32_t vout,n,len,isspecial,retval = -1; uint64_t value; uint256 txid; sprintf(params,"[\"%s\", 1]",txidstr); if ( (retstr= komodo_issuemethod((char *)"getrawtransaction",params,port)) != 0 ) { @@ -105,6 +209,7 @@ int32_t komodo_gateway_tx(char *symbol,int32_t height,int32_t txi,char *txidstr, for (vout=0; voutinitflag == 0 ) + { + portable_mutex_init(&queue->mutex); + queue->initflag = 1; + } + portable_mutex_lock(&queue->mutex); +} + +void queue_enqueue(char *name,queue_t *queue,struct queueitem *origitem,int32_t offsetflag) +{ + struct queueitem *item; + if ( queue->name[0] == 0 && name != 0 && name[0] != 0 ) + strcpy(queue->name,name);//,sizeof(queue->name)); + if ( origitem == 0 ) + { + printf("FATAL type error: queueing empty value\n");//, getchar(); + return; + } + //fprintf(stderr,"enqueue.(%s) %p offset.%d\n",queue->name,origitem,offsetflag); + lock_queue(queue); + item = (struct queueitem *)((long)origitem - offsetflag*sizeof(struct queueitem)); + DL_APPEND(queue->list,item); + portable_mutex_unlock(&queue->mutex); + //printf("queue_enqueue name.(%s) origitem.%p append.%p list.%p\n",name,origitem,item,queue->list); +} + +void *queue_dequeue(queue_t *queue,int32_t offsetflag) +{ + struct queueitem *item = 0; + lock_queue(queue); + if ( queue->list != 0 ) + { + item = queue->list; + //printf("queue_dequeue name.(%s) dequeue.%p list.%p\n",queue->name,item,queue->list); + DL_DELETE(queue->list,item); + } + portable_mutex_unlock(&queue->mutex); + if ( item != 0 && offsetflag != 0 ) + return((void *)((long)item + sizeof(struct queueitem))); + else return(item); +} + +void *queue_delete(queue_t *queue,struct queueitem *copy,int32_t copysize,int32_t freeitem) +{ + struct allocitem *ptr; + struct queueitem *item = 0; + lock_queue(queue); + if ( queue->list != 0 ) + { + DL_FOREACH(queue->list,item) + { + ptr = (void *)((long)item - sizeof(struct allocitem)); + if ( item == copy || (ptr->allocsize == copysize && memcmp((void *)((long)item + sizeof(struct queueitem)),(void *)((long)item + sizeof(struct queueitem)),copysize) == 0) ) + { + DL_DELETE(queue->list,item); + portable_mutex_unlock(&queue->mutex); + //printf("name.(%s) deleted item.%p list.%p\n",queue->name,item,queue->list); + if ( freeitem != 0 ) + myfree(item,copysize); + return(item); + } + } + } + portable_mutex_unlock(&queue->mutex); + return(0); +} + +void *queue_free(queue_t *queue) +{ + struct queueitem *item = 0; + lock_queue(queue); + if ( queue->list != 0 ) + { + DL_FOREACH(queue->list,item) + { + DL_DELETE(queue->list,item); + myfree(item,sizeof(struct queueitem)); + } + //printf("name.(%s) dequeue.%p list.%p\n",queue->name,item,queue->list); + } + portable_mutex_unlock(&queue->mutex); + return(0); +} + +void *queue_clone(queue_t *clone,queue_t *queue,int32_t size) +{ + struct queueitem *ptr,*item = 0; + lock_queue(queue); + if ( queue->list != 0 ) + { + DL_FOREACH(queue->list,item) + { + ptr = mycalloc('c',1,sizeof(*ptr)); + memcpy(ptr,item,size); + queue_enqueue(queue->name,clone,ptr,0); + } + //printf("name.(%s) dequeue.%p list.%p\n",queue->name,item,queue->list); + } + portable_mutex_unlock(&queue->mutex); + return(0); +} + +int32_t queue_size(queue_t *queue) +{ + int32_t count = 0; + struct queueitem *tmp; + lock_queue(queue); + DL_COUNT(queue->list,tmp,count); + portable_mutex_unlock(&queue->mutex); + return count; +} diff --git a/src/tinyformat.h b/src/tinyformat.h index 73d49a1fe..7d3de1de2 100644 --- a/src/tinyformat.h +++ b/src/tinyformat.h @@ -469,7 +469,7 @@ class FormatIterator void finish() { // It would be nice if we could do this from the destructor, but we - // can't if TINFORMAT_ERROR is used to throw an exception! + // can't if TINYFORMAT_ERROR is used to throw an exception! m_fmt = printFormatStringLiteral(m_out, m_fmt); if(*m_fmt != '\0') TINYFORMAT_ERROR("tinyformat: Too many conversion specifiers in format string"); diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 8710f96f8..ee58ed703 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -2592,8 +2592,7 @@ bool CWallet::CreateTransaction(const vector& vecSend, } else { - // Insert change txn at random position: - nChangePosRet = GetRandInt(txNew.vout.size() + 1*0); // all but last position + nChangePosRet = txNew.vout.size() - 1; // dont change first or last vector::iterator position = txNew.vout.begin()+nChangePosRet; txNew.vout.insert(position, newTxOut); }