diff --git a/iguana/dPoW.h b/iguana/dPoW.h index 7e3a8ca33..7862fe36d 100755 --- a/iguana/dPoW.h +++ b/iguana/dPoW.h @@ -23,7 +23,7 @@ #define DPOW_MIN_ASSETCHAIN_SIGS 11 //#define DPOW_M(bp) ((bp)->minsigs) // (((bp)->numnotaries >> 1) + 1) #define DPOW_MODIND(bp,offset) (((((bp)->height / DPOW_CHECKPOINTFREQ) % (bp)->numnotaries) + (offset)) % (bp)->numnotaries) -#define DPOW_VERSION 0x0781 +#define DPOW_VERSION 0x1781 #define DPOW_UTXOSIZE 50000 #define DPOW_MINOUTPUT 6000 #define DPOW_DURATION 600 diff --git a/iguana/dpow/dpow_fsm.c b/iguana/dpow/dpow_fsm.c index bf68ebf19..793c255a7 100755 --- a/iguana/dpow/dpow_fsm.c +++ b/iguana/dpow/dpow_fsm.c @@ -162,9 +162,54 @@ int32_t dpow_checkutxo(struct supernet_info *myinfo,struct dpow_info *dp,struct uint32_t Numallocated; -int32_t dpow_txhasnotarization(int32_t *nothtp,struct supernet_info *myinfo,struct iguana_info *coin,bits256 txid,int32_t height) +int32_t dpow_opreturn_parsesrc(bits256 *blockhashp,int32_t *heightp,bits256 *txidp,char *symbol,bits256 *MoMp,uint32_t *MoMdepthp,uint8_t *opret,int32_t opretlen) { - cJSON *txobj,*vins,*vin,*vouts,*vout,*spentobj,*sobj; char *hexstr; uint8_t script[35]; bits256 spenttxid; uint64_t notarymask; int32_t i,j,numnotaries,len,spentvout,numvins,numvouts,hasnotarization = 0; + int32_t i,c,len,offset = 0; uint8_t op; + symbol[0] = 0; + memset(blockhashp->bytes,0,sizeof(*blockhashp)); + memset(heightp,0,sizeof(*heightp)); + memset(txidp->bytes,0,sizeof(*txidp)); + memset(MoMp->bytes,0,sizeof(*MoMp)); + memset(MoMdepthp,0,sizeof(*MoMdepthp)); + if ( opret[offset++] == 0x6a ) + { + if ( (op= opret[offset++]) < 0x4c ) + len = op; + else if ( op == 0x4c ) + len = opret[offset++]; + else if ( op == 0x4d ) + { + len = opret[offset++]; + len = len + ((int32_t)opret[offset++] << 8); + } else return(-1); + offset += iguana_rwbignum(0,&opret[offset],sizeof(*blockhashp),blockhashp->bytes); + offset += iguana_rwnum(0,&opret[offset],sizeof(*heightp),(uint32_t *)heightp); + offset += iguana_rwbignum(0,&opret[offset],sizeof(*txidp),txidp->bytes); + for (i=0; i<65; i++) + { + if ( (c= opret[offset++]) == 0 ) + { + symbol[i] = 0; + break; + } + if ( offset > opretlen ) + break; + symbol[i] = c; + } + if ( offset+sizeof(bits256)+sizeof(uint32_t) <= opretlen ) + { + offset += iguana_rwbignum(0,&opret[offset],sizeof(*MoMp),MoMp->bytes); + offset += iguana_rwnum(0,&opret[offset],sizeof(*MoMdepthp),(uint32_t *)MoMdepthp); + } + ///printf("offset.%d vs len.%d\n",offset,len); + return(len); + } + return(-1); +} + +int32_t dpow_txhasnotarization(uint64_t *signedmaskp,int32_t *nothtp,struct supernet_info *myinfo,struct iguana_info *coin,bits256 txid,int32_t height) +{ + cJSON *txobj,*vins,*vin,*vouts,*vout,*spentobj,*sobj; char *hexstr; uint8_t script[256]; bits256 spenttxid; uint64_t notarymask=0; int32_t i,j,numnotaries,len,spentvout,numvins,numvouts,hasnotarization = 0; if ( (txobj= dpow_gettransaction(myinfo,coin,txid)) != 0 ) { if ( (vins= jarray(&numvins,txobj,"vin")) != 0 ) @@ -184,7 +229,7 @@ int32_t dpow_txhasnotarization(int32_t *nothtp,struct supernet_info *myinfo,stru if ( spentvout < numvouts ) { vout = jitem(vouts,spentvout); - if ( (sobj= jobj(vout,"scriptPubKey")) != 0 && (hexstr= jstr(sobj,"hex")) != 0 && (len= is_hexstr(hexstr,0)) == sizeof(script)*2 ) + if ( (sobj= jobj(vout,"scriptPubKey")) != 0 && (hexstr= jstr(sobj,"hex")) != 0 && (len= is_hexstr(hexstr,0)) == 35*2 ) { len >>= 1; decode_hex(script,len,hexstr); @@ -216,26 +261,44 @@ int32_t dpow_txhasnotarization(int32_t *nothtp,struct supernet_info *myinfo,stru { hasnotarization = 1; *nothtp = height - 10; - printf("numnotaries.%d %s hasnotarization.%d ht.%d MUSTFIX notht.%d\n",numnotaries,coin->symbol,hasnotarization,height,*nothtp); + if ( (vouts= jarray(&numvouts,txobj,"vout")) != 0 ) + { + bits256 blockhash,txid,MoM; uint32_t MoMdepth; char symbol[65],str[65],str2[65],str3[65]; + vout = jitem(vouts,numvouts-1); + if ( (sobj= jobj(vout,"scriptPubKey")) != 0 && (hexstr= jstr(sobj,"hex")) != 0 && (len= is_hexstr(hexstr,0)) > 36 && len < sizeof(script) ) + { + len >>= 1; + decode_hex(script,len,hexstr); + if ( dpow_opreturn_parsesrc(&blockhash,nothtp,&txid,symbol,&MoM,&MoMdepth,script,len) > 0 ) + { + if ( bits256_nonz(MoM) == 0 || MoMdepth == 0 || *nothtp >= height || *nothtp < 0 ) + *nothtp = 0; + printf("%s.%d notarizationht.%d %s -> %s MoM.%s [%d]\n",symbol,height,*nothtp,bits256_str(str,blockhash),bits256_str(str2,txid),bits256_str(str3,MoM),MoMdepth); + } + } + } } } } } free_json(txobj); } + if ( hasnotarization != 0 ) + (*signedmaskp) = notarymask; return(hasnotarization); } -int32_t dpow_hasnotarization(int32_t *nothtp,struct supernet_info *myinfo,struct iguana_info *coin,cJSON *blockjson,int32_t ht) +int32_t dpow_hasnotarization(uint64_t *signedmaskp,int32_t *nothtp,struct supernet_info *myinfo,struct iguana_info *coin,cJSON *blockjson,int32_t ht) { int32_t i,n,hasnotarization = 0; bits256 txid; cJSON *txarray; *nothtp = 0; + *signedmaskp = 0; if ( (txarray= jarray(&n,blockjson,"tx")) != 0 ) { for (i=0; isymbol,height); @@ -256,13 +319,13 @@ bits256 dpow_calcMoM(uint32_t *MoMdepthp,struct supernet_info *myinfo,struct igu merkles = calloc(3*maxdepth+1,sizeof(*merkles)); merkles[MoMdepth++] = merkle; ht = height - MoMdepth; - while ( MoMdepth < maxdepth && ht >= breakht && ht > 0 ) + while ( MoMdepth < maxdepth && ht > breakht && ht > 0 ) { //fprintf(stderr,"%s.%d ",coin->symbol,ht); blockhash = dpow_getblockhash(myinfo,coin,ht); if ( (blockjson= dpow_getblock(myinfo,coin,blockhash)) != 0 ) { - if ( breakht == 0 && dpow_hasnotarization(¬ht,myinfo,coin,blockjson,ht) > 0 ) + if ( breakht == 0 && dpow_hasnotarization(&signedmask,¬ht,myinfo,coin,blockjson,ht) > 0 ) { breakht = notht; //free_json(blockjson); diff --git a/iguana/dpow/dpow_network.c b/iguana/dpow/dpow_network.c index 0da39c78d..27ebcf91e 100755 --- a/iguana/dpow/dpow_network.c +++ b/iguana/dpow/dpow_network.c @@ -2243,7 +2243,7 @@ int32_t dpow_rwopret(int32_t rwflag,uint8_t *opret,bits256 *hashmsg,int32_t *hei { memcpy(&opret[opretlen],extras,extralen); opretlen += extralen; - printf("added extra.%d crc.%08x\n",extralen,calc_crc32(0,extras,extralen)); + //printf("added extra.%d crc.%08x\n",extralen,calc_crc32(0,extras,extralen)); } } else diff --git a/iguana/iguana_notary.c b/iguana/iguana_notary.c index f56bb4c79..9f94fb4ea 100755 --- a/iguana/iguana_notary.c +++ b/iguana/iguana_notary.c @@ -60,7 +60,7 @@ void dpow_checkpointset(struct supernet_info *myinfo,struct dpow_checkpoint *che void dpow_srcupdate(struct supernet_info *myinfo,struct dpow_info *dp,int32_t height,bits256 hash,uint32_t timestamp,uint32_t blocktime) { - void **ptrs; char str[65]; cJSON *blockjson; struct iguana_info *coin; struct dpow_checkpoint checkpoint; int32_t freq,minsigs,i,ht,notht; struct dpow_block *bp; + void **ptrs; char str[65]; cJSON *blockjson; struct iguana_info *coin; struct dpow_checkpoint checkpoint; int32_t freq,minsigs,i,ht,notht; uint64_t signedmask; struct dpow_block *bp; dpow_checkpointset(myinfo,&dp->last,height,hash,timestamp,blocktime); checkpoint = dp->srcfifo[dp->srcconfirms]; if ( strcmp("BTC",dp->dest) == 0 ) @@ -88,7 +88,7 @@ void dpow_srcupdate(struct supernet_info *myinfo,struct dpow_info *dp,int32_t he if ( (blockjson= dpow_getblock(myinfo,coin,hash)) != 0 ) { height = jint(blockjson,"height"); - if ( dpow_hasnotarization(¬ht,myinfo,coin,blockjson,height) <= 0 ) + if ( dpow_hasnotarization(&signedmask,¬ht,myinfo,coin,blockjson,height) <= 0 ) { blocktime = juint(blockjson,"time"); free_json(blockjson); @@ -575,6 +575,58 @@ void iguana_notarystats(int32_t totals[64],int32_t dispflag) } } +STRING_AND_TWOINTS(dpow,notarizations,symbol,height,numblocks) +{ + int32_t i,j,ht,maxheight,notht,masksums[64]; uint64_t signedmask; cJSON *retjson,*blockjson,*item,*array; bits256 blockhash; + memset(masksums,0,sizeof(masksums)); + ht = height; + if ( (coin= iguana_coinfind(symbol)) != 0 ) + { + if ( (retjson= dpow_getinfo(myinfo,coin)) != 0 ) + { + maxheight = jint(retjson,"blocks"); + free_json(retjson); + } else maxheight = (1 << 30); + for (i=0; i maxheight ) + break; + blockhash = dpow_getblockhash(myinfo,coin,ht); + if ( (blockjson= dpow_getblock(myinfo,coin,blockhash)) != 0 ) + { + if ( dpow_hasnotarization(&signedmask,¬ht,myinfo,coin,blockjson,ht) > 0 ) + { + for (j=0; j<64; j++) + if ( ((1LL << j) & signedmask) != 0 ) + masksums[j]++; + } + free_json(blockjson); + } + } + array = cJSON_CreateArray(); + for (i=0; i