diff --git a/deprecated/obsolete.h b/deprecated/obsolete.h index 2859d8b13..def4f1fa0 100755 --- a/deprecated/obsolete.h +++ b/deprecated/obsolete.h @@ -19189,3 +19189,101 @@ len = 0; } else retstr = clonestr("{\"error\":\"missing or invalid fields\"}"); return(retstr); }*/ + + int32_t dpow_message_utxo(uint8_t *senderpub,bits256 *hashmsgp,bits256 *txidp,int32_t *voutp,bits256 *commitp,cJSON *json) + { + cJSON *msgobj,*item; uint8_t key[BASILISK_KEYSIZE],data[4096]; char *keystr,*hexstr; int32_t i,n,datalen,retval = -1; //,str[65],str2[65] + *voutp = -1; + memset(txidp,0,sizeof(*txidp)); + if ( (msgobj= jarray(&n,json,"messages")) != 0 ) + { + //printf("messages.(%s)\n",jprint(msgobj,0)); + for (i=0; i 0 ) + { + decode_hex(key,BASILISK_KEYSIZE,keystr); + datalen >>= 1; + decode_hex(data,datalen,hexstr); + retval = dpow_rwutxobuf(0,data,hashmsgp,txidp,voutp,commitp,senderpub); + //printf("notary.%d hashmsg.(%s) txid.(%s) v%d\n",i,bits256_str(str,*hashmsgp),bits256_str(str2,*txidp),*voutp); + } + } + } + return(retval); + } + int32_t dpow_message_most(struct dpow_sigentry *dsigs,int32_t num,cJSON *json,int32_t lastflag) + { + cJSON *msgobj,*item; uint8_t key[BASILISK_KEYSIZE]; struct dpow_sigentry dsig; char *keystr,*hexstr; uint8_t data[sizeof(struct dpow_sigentry)]; int32_t duplicate,i,j,n,datalen,most = 0; + if ( (msgobj= jarray(&n,json,"messages")) != 0 ) + { + for (i=0; i 0 ) + { + decode_hex(key,BASILISK_KEYSIZE,keystr); + datalen >>= 1; + if ( datalen <= sizeof(data) ) + { + decode_hex(data,datalen,hexstr); + dpow_rwsigentry(0,data,&dsig); + for (j=duplicate=0; j= maxlen.%d\n",datalen,(int32_t)sizeof(data)); + } + } + } + if ( lastflag != 0 && num > 0 ) + { + for (j=0; j most ) + { + most = n; + dsigs[num] = dsigs[j]; + } + printf("lastflag.%d num.%d most.%d n.%d refcount.%d\n",lastflag,num,most,n,dsigs[j].refcount); + } + } + return(num); + } + + int32_t dpow_dsigs_match(struct dpow_entry notaries[DPOW_MAXRELAYS],int32_t numnotaries,struct dpow_sigentry *dsigs,int32_t num,int32_t refk,uint64_t refmask,int32_t refheight) + { + struct dpow_sigentry dsig; int32_t i,senderind,matches = 0; + for (i=0; i= 0 && dsig.lastk == refk && dsig.mask == refmask ) + { + if ( (notaries[senderind].siglen= dsig.siglen) < sizeof(notaries[senderind].sig) ) + { + notaries[senderind].k = refk; + notaries[senderind].mask = refmask; + notaries[senderind].beacon = dsig.beacon; + memcpy(notaries[senderind].sig,dsig.sig,dsig.siglen); + int32_t j; for (j=0; j 0 ) + printf(" <- sender.%d siglen.%d\n",i,dsig.siglen); + matches++; + } + } else printf("skip senderind.%d numnotaries.%d lastk.%d refk.%d mask.%llx refmask.%llx refheight.%d\n",senderind,numnotaries,dsig.lastk,refk,(long long)dsig.mask,(long long)refmask,refheight); + } + //printf("matches.%d num.%d k.%d %llx refht.%d\n",matches,num,refk,(long long)refmask,refheight); + return(matches); + } diff --git a/iguana/dPoW.h b/iguana/dPoW.h index c8a2c5fa1..c822b787c 100755 --- a/iguana/dPoW.h +++ b/iguana/dPoW.h @@ -28,9 +28,9 @@ struct dpow_entry { bits256 prev_hash,commit,beacon; - uint64_t mask; + uint64_t masks[DPOW_MAXRELAYS]; int32_t prev_vout,height; - uint8_t pubkey[33],k,siglen,sig[76]; + uint8_t pubkey[33],siglens[DPOW_MAXRELAYS],sigs[DPOW_MAXRELAYS][76]; }; struct dpow_sigentry @@ -54,6 +54,7 @@ struct dpow_checkpoint { struct dpow_hashheight blockhash,approved; bits256 mine struct dpow_block { bits256 hashmsg,btctxid,signedtxid,beacon,commit; + struct iguana_info *coin; char *opret_symbol; uint64_t recvmask; struct dpow_entry notaries[DPOW_MAXRELAYS]; uint32_t state,timestamp; diff --git a/iguana/iguana_notary.c b/iguana/iguana_notary.c index f906a0cb8..22591996b 100755 --- a/iguana/iguana_notary.c +++ b/iguana/iguana_notary.c @@ -144,7 +144,7 @@ int32_t dpow_sigbufcmp(int32_t *duplicatep,struct dpow_sigentry *dsig,struct dpo return(-1); } -bits256 dpow_notarytx(char *signedtx,int32_t isPoS,uint32_t timestamp,int32_t height,struct dpow_entry notaries[DPOW_MAXRELAYS],int32_t numnotaries,uint64_t mask,int32_t k,bits256 hashmsg,int32_t heightmsg,bits256 btctxid,char *src) +bits256 dpow_notarytx(char *signedtx,int32_t isPoS,struct dpow_block *bp,uint64_t mask,int32_t lastk,char *src) { uint32_t i,j,m,locktime,numvouts,version,opretlen,siglen,len,sequenceid = 0xffffffff; uint64_t satoshis,satoshisB; uint8_t serialized[16384],opret[1024],data[4096]; @@ -152,24 +152,24 @@ bits256 dpow_notarytx(char *signedtx,int32_t isPoS,uint32_t timestamp,int32_t he version = 1; len += iguana_rwnum(1,&serialized[len],sizeof(version),&version); if ( isPoS != 0 ) - len += iguana_rwnum(1,&serialized[len],sizeof(timestamp),×tamp); - m = (numnotaries >> 1) + 1; + len += iguana_rwnum(1,&serialized[len],sizeof(bp->timestamp),&bp->timestamp); + m = (bp->numnotaries >> 1) + 1; len += iguana_rwvarint32(1,&serialized[len],(uint32_t *)&m); - for (j=m=0; jnumnotaries; j++) { - i = ((height % numnotaries) + j) % numnotaries; + i = ((bp->height % bp->numnotaries) + j) % bp->numnotaries; if ( ((1LL << i) & mask) != 0 ) { - len += iguana_rwbignum(1,&serialized[len],sizeof(notaries[i].prev_hash),notaries[i].prev_hash.bytes); - len += iguana_rwnum(1,&serialized[len],sizeof(notaries[i].prev_vout),¬aries[i].prev_vout); - siglen = notaries[i].siglen; + len += iguana_rwbignum(1,&serialized[len],sizeof(bp->notaries[i].prev_hash),bp->notaries[i].prev_hash.bytes); + len += iguana_rwnum(1,&serialized[len],sizeof(bp->notaries[i].prev_vout),&bp->notaries[i].prev_vout); + siglen = bp->notaries[i].siglens[lastk]; len += iguana_rwvarint32(1,&serialized[len],&siglen); if ( siglen > 0 ) - memcpy(&serialized[len],notaries[i].sig,siglen), len += siglen; + memcpy(&serialized[len],bp->notaries[i].sigs[lastk],siglen), len += siglen; len += iguana_rwnum(1,&serialized[len],sizeof(sequenceid),&sequenceid); //printf("height.%d mod.%d VINI.%d <- i.%d j.%d\n",height,height % numnotaries,m,i,j); m++; - if ( m == numnotaries/2+1 && i == k ) + if ( m == bp->numnotaries/2+1 && i == lastk ) break; } } @@ -185,7 +185,7 @@ bits256 dpow_notarytx(char *signedtx,int32_t isPoS,uint32_t timestamp,int32_t he serialized[len++] = CHECKSIG; satoshis = 0; len += iguana_rwnum(1,&serialized[len],sizeof(satoshis),&satoshis); - opretlen = dpow_rwopret(1,opret,&hashmsg,&heightmsg,&btctxid,src); + opretlen = dpow_rwopret(1,opret,&bp->hashmsg,&bp->height,&bp->btctxid,src); opretlen = dpow_opreturnscript(data,opret,opretlen); if ( opretlen < 0xfd ) serialized[len++] = opretlen; @@ -500,65 +500,41 @@ int32_t dpow_haveutxo(struct supernet_info *myinfo,struct iguana_info *coin,bits return(haveutxo); } -int32_t dpow_message_utxo(uint8_t *senderpub,bits256 *hashmsgp,bits256 *txidp,int32_t *voutp,bits256 *commitp,cJSON *json) -{ - cJSON *msgobj,*item; uint8_t key[BASILISK_KEYSIZE],data[4096]; char *keystr,*hexstr; int32_t i,n,datalen,retval = -1; //,str[65],str2[65] - *voutp = -1; - memset(txidp,0,sizeof(*txidp)); - if ( (msgobj= jarray(&n,json,"messages")) != 0 ) - { - //printf("messages.(%s)\n",jprint(msgobj,0)); - for (i=0; i 0 ) - { - decode_hex(key,BASILISK_KEYSIZE,keystr); - datalen >>= 1; - decode_hex(data,datalen,hexstr); - retval = dpow_rwutxobuf(0,data,hashmsgp,txidp,voutp,commitp,senderpub); - //printf("notary.%d hashmsg.(%s) txid.(%s) v%d\n",i,bits256_str(str,*hashmsgp),bits256_str(str2,*txidp),*voutp); - } - } - } - return(retval); -} - -cJSON *dpow_createtx(struct iguana_info *coin,cJSON **vinsp,struct dpow_entry notaries[DPOW_MAXRELAYS],int32_t numnotaries,int32_t height,int32_t lastk,uint64_t mask,int32_t usesigs,bits256 hashmsg,bits256 btctxid,uint32_t timestamp) +cJSON *dpow_createtx(struct iguana_info *coin,cJSON **vinsp,struct dpow_block *bp,int32_t lastk,uint64_t mask,int32_t usesigs) { int32_t i,j,m=0,siglen; char scriptstr[256]; cJSON *txobj=0,*vins=0,*item; uint64_t satoshis; uint8_t script[35],*sig; if ( (txobj= bitcoin_txcreate(coin->chain->isPoS,0,1,0)) != 0 ) { jaddnum(txobj,"suppress",1); - jaddnum(txobj,"timestamp",timestamp); + jaddnum(txobj,"timestamp",bp->timestamp); vins = cJSON_CreateArray(); - for (j=0; jnumnotaries; j++) { - i = ((height % numnotaries) + j) % numnotaries; + i = ((bp->height % bp->numnotaries) + j) % bp->numnotaries; if ( ((1LL << i) & mask) != 0 ) { item = cJSON_CreateObject(); - jaddbits256(item,"txid",notaries[i].prev_hash); - jaddnum(item,"vout",notaries[i].prev_vout); + jaddbits256(item,"txid",bp->notaries[i].prev_hash); + jaddnum(item,"vout",bp->notaries[i].prev_vout); script[0] = 33; - memcpy(script+1,notaries[i].pubkey,33); + memcpy(script+1,bp->notaries[i].pubkey,33); script[34] = CHECKSIG; init_hexbytes_noT(scriptstr,script,35); jaddstr(item,"scriptPubKey",scriptstr); sig = 0, siglen = 0; - if ( usesigs != 0 && notaries[i].siglen > 0 ) + if ( usesigs != 0 && bp->notaries[i].siglens[lastk] > 0 ) { - init_hexbytes_noT(scriptstr,notaries[i].sig,notaries[i].siglen); + init_hexbytes_noT(scriptstr,bp->notaries[i].sigs[lastk],bp->notaries[i].siglens[lastk]); jaddstr(item,"scriptSig",scriptstr); printf("sig%d.(%s)\n",i,scriptstr); - sig = notaries[i].sig; - siglen = notaries[i].siglen; + sig = bp->notaries[i].sigs[lastk]; + siglen = bp->notaries[i].siglens[lastk]; } jaddi(vins,item); - bitcoin_txinput(coin,txobj,notaries[i].prev_hash,notaries[i].prev_vout,0xffffffff,script,sizeof(script),0,0,0,0,sig,siglen); + bitcoin_txinput(coin,txobj,bp->notaries[i].prev_hash,bp->notaries[i].prev_vout,0xffffffff,script,sizeof(script),0,0,0,0,sig,siglen); //printf("height.%d mod.%d VINI.%d <- i.%d j.%d\n",height,height % numnotaries,m,i,j); m++; - if ( m == numnotaries/2+1 && i == lastk ) + if ( m == bp->numnotaries/2+1 && i == lastk ) break; } } @@ -574,74 +550,25 @@ cJSON *dpow_createtx(struct iguana_info *coin,cJSON **vinsp,struct dpow_entry no return(txobj); } -int32_t dpow_message_most(struct dpow_sigentry *dsigs,int32_t num,cJSON *json,int32_t lastflag) -{ - cJSON *msgobj,*item; uint8_t key[BASILISK_KEYSIZE]; struct dpow_sigentry dsig; char *keystr,*hexstr; uint8_t data[sizeof(struct dpow_sigentry)]; int32_t duplicate,i,j,n,datalen,most = 0; - if ( (msgobj= jarray(&n,json,"messages")) != 0 ) - { - for (i=0; i 0 ) - { - decode_hex(key,BASILISK_KEYSIZE,keystr); - datalen >>= 1; - if ( datalen <= sizeof(data) ) - { - decode_hex(data,datalen,hexstr); - dpow_rwsigentry(0,data,&dsig); - for (j=duplicate=0; j= maxlen.%d\n",datalen,(int32_t)sizeof(data)); - } - } - } - if ( lastflag != 0 && num > 0 ) - { - for (j=0; j most ) - { - most = n; - dsigs[num] = dsigs[j]; - } - printf("lastflag.%d num.%d most.%d n.%d refcount.%d\n",lastflag,num,most,n,dsigs[j].refcount); - } - } - return(num); -} - -int32_t dpow_signedtxgen(struct supernet_info *myinfo,struct dpow_info *dp,struct iguana_info *coin,bits256 *signedtxidp,char *signedtx,uint64_t mask,int32_t lastk,struct dpow_entry notaries[DPOW_MAXRELAYS],int32_t numnotaries,int32_t height,int32_t myind,bits256 hashmsg,bits256 btctxid,uint32_t timestamp,bits256 beacon) +int32_t dpow_signedtxgen(struct supernet_info *myinfo,struct iguana_info *coin,struct dpow_block *bp,uint64_t mask,int32_t lastk,int32_t myind,char *opret_symbol) { - int32_t i,j,z,m=0,datalen,incr,retval=-1; char rawtx[16384],*jsonstr,*rawtx2,*sigstr; cJSON *txobj,*signobj,*sobj,*txobj2,*vins,*item,*vin; uint8_t data[sizeof(struct dpow_sigentry)]; bits256 txid,srchash,desthash; uint32_t channel; struct dpow_sigentry dsig; - //incr = sqrt(numnotaries) + 1; - //if ( numnotaries < 8 ) + int32_t i,j,z,m=0,datalen,incr,retval=-1; char rawtx[16384],*jsonstr,*signedtx,*rawtx2,*sigstr; cJSON *txobj,*signobj,*sobj,*txobj2,*vins,*item,*vin; uint8_t data[sizeof(struct dpow_sigentry)]; bits256 txid,srchash,desthash; uint32_t channel; struct dpow_sigentry dsig; + if ( bp->numnotaries < 8 ) incr = 1; + else incr = sqrt(bp->numnotaries) + 1; memset(&dsig,0,sizeof(dsig)); dsig.lastk = lastk; dsig.mask = mask; dsig.senderind = myind; - dsig.beacon = beacon; + dsig.beacon = bp->beacon; channel = DPOW_SIGCHANNEL; - if ( bits256_nonz(btctxid) == 0 ) + if ( bits256_nonz(bp->btctxid) == 0 ) channel = DPOW_SIGBTCCHANNEL; for (j=0; jDPOW.minerkey33[j+1]; - if ( (txobj= dpow_createtx(coin,&vins,notaries,numnotaries,height,lastk,mask,1,hashmsg,btctxid,timestamp)) != 0 ) + if ( (txobj= dpow_createtx(coin,&vins,bp,lastk,mask,1)) != 0 ) { - txid = dpow_notarytx(rawtx,coin->chain->isPoS,timestamp,height,notaries,numnotaries,mask,lastk,hashmsg,height,btctxid,dp->symbol); + txid = dpow_notarytx(rawtx,coin->chain->isPoS,bp,mask,lastk,opret_symbol); if ( rawtx[0] != 0 ) { if ( (jsonstr= dpow_signrawtransaction(myinfo,coin,rawtx,vins)) != 0 ) @@ -665,13 +592,13 @@ int32_t dpow_signedtxgen(struct supernet_info *myinfo,struct dpow_info *dp,struc decode_hex(dsig.sig,dsig.siglen,sigstr); datalen = dpow_rwsigentry(1,data,&dsig); printf(">>>>>>>> datalen.%d siglen.%d myind.%d lastk.%d mask.%llx\n",datalen,dsig.siglen,dsig.senderind,dsig.lastk,(long long)dsig.mask); - for (i=0; inumnotaries; i+=incr) { if ( i != myind ) printf("send siglen.%d -> notary.%d\n",dsig.siglen,i); for (z=0; znotaries[i].pubkey[z+1]; + basilisk_channelsend(myinfo,srchash,desthash,channel,bp->height,data,datalen,120); } retval = 0; break; @@ -694,126 +621,37 @@ int32_t dpow_signedtxgen(struct supernet_info *myinfo,struct dpow_info *dp,struc return(retval); } -int32_t dpow_dsigs_match(struct dpow_entry notaries[DPOW_MAXRELAYS],int32_t numnotaries,struct dpow_sigentry *dsigs,int32_t num,int32_t refk,uint64_t refmask,int32_t refheight) +int32_t dpow_mostsignedtx(struct supernet_info *myinfo,struct dpow_info *dp,struct iguana_info *coin,uint64_t *maskp,int32_t *lastkp,struct dpow_block *bp,int32_t myind) { - struct dpow_sigentry dsig; int32_t i,senderind,matches = 0; - for (i=0; inumnotaries; k++) { - dsig = dsigs[i]; - if ( (senderind= dsig.senderind) < numnotaries && senderind >= 0 && dsig.lastk == refk && dsig.mask == refmask ) + for (i=0; inumnotaries; i++) { - if ( (notaries[senderind].siglen= dsig.siglen) < sizeof(notaries[senderind].sig) ) + ep = &bp->notaries[i]; + if ( ep->masks[k] != 0 ) { - notaries[senderind].k = refk; - notaries[senderind].mask = refmask; - notaries[senderind].beacon = dsig.beacon; - memcpy(notaries[senderind].sig,dsig.sig,dsig.siglen); - int32_t j; for (j=0; j 0 ) - printf(" <- sender.%d siglen.%d\n",i,dsig.siglen); - matches++; + if ( nonz == 0 ) + refmask = ep->masks[k], nonz++; + else if ( ep->masks[k] != refmask ) + printf("refk.%d refmask.%llx but got %llx\n",k,(long long)refmask,(long long)ep->masks[k]); } - } else printf("skip senderind.%d numnotaries.%d lastk.%d refk.%d mask.%llx refmask.%llx refheight.%d\n",senderind,numnotaries,dsig.lastk,refk,(long long)dsig.mask,(long long)refmask,refheight); - } - //printf("matches.%d num.%d k.%d %llx refht.%d\n",matches,num,refk,(long long)refmask,refheight); - return(matches); -} - -int32_t dpow_mostsignedtx(struct supernet_info *myinfo,struct dpow_info *dp,struct iguana_info *coin,bits256 *signedtxidp,char *signedtx,uint64_t *maskp,int32_t *lastkp,struct dpow_entry notaries[DPOW_MAXRELAYS],int32_t numnotaries,int32_t height,int32_t myind,bits256 hashmsg,bits256 btctxid,uint32_t timestamp,bits256 beacon) -{ - uint32_t channel; struct dpow_sigentry *dsigs,dsig; bits256 srchash; int32_t num,j,most = 0; - memset(signedtxidp,0,sizeof(*signedtxidp)); - signedtx[0] = 0; - channel = DPOW_SIGCHANNEL; - if ( bits256_nonz(btctxid) == 0 ) - channel = DPOW_SIGBTCCHANNEL; - for (j=0; jDPOW.minerkey33[j+1]; - num = 0; - memset(&dsig,0,sizeof(dsig)); - dsigs = calloc(4096,sizeof(struct dpow_sigentry)); - /*for (i=0; i most ) { - //printf("RETARRAY.(%s)\n",jprint(retarray,0)); - if ( (m= cJSON_GetArraySize(retarray)) != 0 ) - { - for (k=0; k 0 ) + } + if ( most > 0 ) { - dsig = dsigs[num]; - if ( dsig.mask != 0 ) - { - *lastkp = dsig.lastk; - *maskp = dsig.mask; - if ( (most= dpow_dsigs_match(notaries,numnotaries,dsigs,num,dsig.lastk,dsig.mask,height)) >= numnotaries/2+1 ) - { - *signedtxidp = dpow_notarytx(signedtx,coin->chain->isPoS,timestamp,height,notaries,numnotaries,dsig.mask,dsig.lastk,hashmsg,height,btctxid,dp->symbol); - } else printf("mostsignedtx most.%d k.%d mask.%llx\n",most,dsig.lastk,(long long)dsig.mask); - } else printf("null mask.0\n"); - } else printf("mostsignedtx num.%d\n",num); - free(dsigs); + *lastkp = mostk; + *maskp = refmask; + bp->signedtxid = dpow_notarytx(bp->signedtx,coin->chain->isPoS,bp,refmask,mostk,dp->symbol); + } else printf("mostsignedtx most.%d\n",most); return(most); } -/*void dpow_txidupdate(struct supernet_info *myinfo,struct dpow_info *dp,struct iguana_info *coin,uint64_t *recvmaskp,uint32_t channel,int32_t height,struct dpow_entry notaries[DPOW_MAXRELAYS],int32_t numnotaries,int32_t myind,bits256 hashmsg) -{ - int32_t j,k,m,vout,flag; cJSON *item,*retarray; uint8_t senderpub[33]; bits256 desthash,commit,srchash,checkmsg,txid; - memset(srchash.bytes,0,sizeof(srchash)); - for (j=0; jDPOW.minerkey33[j+1]; - if ( (retarray= basilisk_channelget(myinfo,srchash,desthash,channel,height,1)) != 0 ) - { - //printf("TXIDUPDATE.(%s)\n",jprint(retarray,0)); - if ( (m= cJSON_GetArraySize(retarray)) != 0 ) - { - for (k=flag=0; k 0 ) - { - if ( bits256_cmp(checkmsg,hashmsg) == 0 ) - { - for (j=0; jkey,&channel,&height,&srchash,&desthash); if ( channel == DPOW_UTXOCHANNEL || channel == DPOW_UTXOBTCCHANNEL ) { dpow_rwutxobuf(0,msg->data,&hashmsg,&txid,&vout,&commit,senderpub); if ( (bp= dpow_heightfind(myinfo,height,channel == DPOW_UTXOBTCCHANNEL)) != 0 ) { + for (i=0; inumnotaries; i++) + { + if ( memcmp(bp->notaries[i].pubkey,myinfo->DPOW.minerkey33,33) == 0 ) + { + myind = i; + break; + } + } + if ( myind < 0 ) + return; if ( bits256_cmp(hashmsg,bp->hashmsg) != 0 ) printf("unexpected mismatch hashmsg.%s vs %s\n",bits256_str(str,hashmsg),bits256_str(str2,bp->hashmsg)); if ( (ep= dpow_notaryfind(myinfo,bp,senderpub)) != 0 ) @@ -871,7 +719,17 @@ void dpow_handler(struct supernet_info *myinfo,struct basilisk_message *msg) ep->prev_vout = vout; ep->commit = commit; ep->height = height; + mask = dpow_lastk_mask(bp,&lastk); + if ( bitweight(mask) >= bp->numnotaries/2+1 ) + { + if ( ep->masks[lastk] == 0 ) + { + if ( dpow_signedtxgen(myinfo,bp->coin,bp,mask,lastk,myind,bp->opret_symbol) == 0 ) + printf("created sig for lastk.%d %llx\n",lastk,(long long)mask); + } + } flag = 1; + printf("from.%ld got ht.%d %s/v%d\n",((long)ep - (long)bp->notaries)/sizeof(*ep),height,bits256_str(str,txid),vout); } } } @@ -881,11 +739,23 @@ void dpow_handler(struct supernet_info *myinfo,struct basilisk_message *msg) else if ( channel == DPOW_SIGCHANNEL || channel == DPOW_SIGBTCCHANNEL ) { dpow_rwsigentry(0,msg->data,&dsig); - if ( (bp= dpow_heightfind(myinfo,height,channel == DPOW_SIGBTCCHANNEL)) != 0 ) + if ( dsig.senderind >= 0 && dsig.senderind < DPOW_MAXRELAYS && (bp= dpow_heightfind(myinfo,height,channel == DPOW_SIGBTCCHANNEL)) != 0 ) { - if ( (ep= dpow_notaryfind(myinfo,bp,dsig.senderpub)) != 0 ) + if ( dsig.lastk < bp->numnotaries && dsig.senderind < bp->numnotaries && (ep= dpow_notaryfind(myinfo,bp,dsig.senderpub)) != 0 ) { - + vcalc_sha256(0,commit.bytes,dsig.beacon.bytes,sizeof(dsig.beacon)); + if ( bits256_cmp(ep->commit,commit) == 0 && memcmp(dsig.senderpub,bp->notaries[dsig.senderind].pubkey,33) == 0 ) + { + if ( ep->masks[dsig.lastk] == 0 ) + { + ep->masks[dsig.lastk] = dsig.mask; + ep->siglens[dsig.lastk] = dsig.siglen; + memcpy(ep->sigs[dsig.lastk],dsig.sig,dsig.siglen); + ep->beacon = dsig.beacon; + printf("from.%d got lastk.%d %llx siglen.%d\n",dsig.senderind,dsig.lastk,(long long)dsig.mask,dsig.siglen); + flag = 1; + } + } else printf("beacon mismatch for senderind.%d\n",dsig.senderind); } } if ( flag == 0 ) @@ -896,14 +766,21 @@ void dpow_handler(struct supernet_info *myinfo,struct basilisk_message *msg) uint32_t dpow_statemachineiterate(struct supernet_info *myinfo,struct dpow_info *dp,struct iguana_info *coin,struct dpow_block *bp,int32_t myind) { // todo: add RBF support - bits256 txid; int32_t vout,i,len,j,k,m,incr,haveutxo = 0; cJSON *addresses; char *sendtx,*rawtx,*retstr,coinaddr[64]; uint8_t data[4096]; uint32_t channel; bits256 srchash,desthash,zero; uint64_t mask; + bits256 txid; int32_t vout,i,len,j,k,m,incr,haveutxo = 0; cJSON *addresses; char *sendtx,*rawtx,*retstr,*opret_symbol,coinaddr[64]; uint8_t data[4096]; uint32_t channel; bits256 srchash,desthash,zero; uint64_t mask; if ( bp->numnotaries > 8 ) incr = sqrt(bp->numnotaries) + 1; else incr = 1; memset(zero.bytes,0,sizeof(zero)); - channel = DPOW_UTXOCHANNEL; if ( bits256_nonz(bp->btctxid) == 0 ) + { channel = DPOW_UTXOBTCCHANNEL; + opret_symbol = ""; + } + else + { + channel = DPOW_UTXOCHANNEL; + opret_symbol = dp->symbol; + } bitcoin_address(coinaddr,coin->chain->pubtype,myinfo->DPOW.minerkey33,33); if ( bits256_nonz(bp->hashmsg) == 0 ) return(0xffffffff); @@ -936,8 +813,7 @@ uint32_t dpow_statemachineiterate(struct supernet_info *myinfo,struct dpow_info if ( (haveutxo= dpow_haveutxo(myinfo,coin,&txid,&vout,coinaddr)) != 0 && vout >= 0 && vout < 0x100 ) { len = dpow_rwutxobuf(1,data,&bp->hashmsg,&txid,&vout,&bp->commit,myinfo->DPOW.minerkey33); - i = ((myind + (uint32_t)rand()) % incr); - for (; inumnotaries; i+=incr) + for (i=((myind + (uint32_t)rand()) % incr); inumnotaries; i+=incr) { for (j=0; jnotaries[i].pubkey[j+1]; @@ -951,13 +827,14 @@ uint32_t dpow_statemachineiterate(struct supernet_info *myinfo,struct dpow_info printf("STATE2: RECVMASK.%llx\n",(long long)bp->recvmask); if ( bitweight(bp->recvmask) > bp->numnotaries/2 ) bp->state = 3; + else bp->state = 2; break; case 3: // create rawtx, sign, send rawtx + sig to all other nodes mask = dpow_lastk_mask(bp,&k); printf("STATE3: %s BTC.%d RECVMASK.%llx mask.%llx\n",coin->symbol,bits256_nonz(bp->btctxid)==0,(long long)bp->recvmask,(long long)mask); - if ( bitweight(mask) == bp->numnotaries/2+1 ) + if ( bitweight(mask) >= bp->numnotaries/2+1 ) { - if ( dpow_signedtxgen(myinfo,dp,coin,&bp->signedtxid,bp->signedtx,mask,k,bp->notaries,bp->numnotaries,bp->height,myind,bp->hashmsg,bp->btctxid,bp->timestamp,bp->beacon) == 0 ) + if ( dpow_signedtxgen(myinfo,coin,bp,mask,k,myind,opret_symbol) == 0 ) { bp->state = 4; } @@ -965,7 +842,7 @@ uint32_t dpow_statemachineiterate(struct supernet_info *myinfo,struct dpow_info break; case 4: // wait for N/2+1 signed tx and broadcast printf("STATE4: %s BTC.%d RECVMASK.%llx\n",coin->symbol,bits256_nonz(bp->btctxid)==0,(long long)bp->recvmask); - if ( (m= dpow_mostsignedtx(myinfo,dp,coin,&bp->signedtxid,bp->signedtx,&mask,&k,bp->notaries,bp->numnotaries,bp->height,myind,bp->hashmsg,bp->btctxid,bp->timestamp,bp->beacon)) > 0 ) + if ( (m= dpow_mostsignedtx(myinfo,dp,coin,&mask,&k,bp,myind)) > 0 ) { if ( m >= bp->numnotaries/2+1 ) { @@ -979,7 +856,7 @@ uint32_t dpow_statemachineiterate(struct supernet_info *myinfo,struct dpow_info } else { - dpow_signedtxgen(myinfo,dp,coin,&bp->signedtxid,bp->signedtx,mask,k,bp->notaries,bp->numnotaries,bp->height,myind,bp->hashmsg,bp->btctxid,bp->timestamp,bp->beacon); + dpow_signedtxgen(myinfo,coin,bp,mask,k,myind,opret_symbol); } } break; @@ -1001,6 +878,8 @@ void dpow_statemachinestart(void *ptr) if ( (destbp= dp->destblocks[checkpoint.blockhash.height]) == 0 ) { destbp = calloc(1,sizeof(*destbp)); + destbp->coin = iguana_coinfind(dp->dest); + destbp->opret_symbol = dp->symbol; dp->destblocks[checkpoint.blockhash.height] = destbp; destbp->beacon = rand256(0); vcalc_sha256(0,destbp->commit.bytes,destbp->beacon.bytes,sizeof(destbp->beacon)); @@ -1014,6 +893,8 @@ void dpow_statemachinestart(void *ptr) if ( (srcbp= dp->srcblocks[checkpoint.blockhash.height]) == 0 ) { srcbp = calloc(1,sizeof(*srcbp)); + srcbp->coin = iguana_coinfind(dp->symbol); + srcbp->opret_symbol = dp->symbol; dp->srcblocks[checkpoint.blockhash.height] = srcbp; srcbp->beacon = destbp->beacon; srcbp->commit = destbp->commit;