/****************************************************************************** * Copyright © 2014-2016 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * * holder information and the developer policies on copyright and licensing. * * * * Unless otherwise agreed in a custom licensing agreement, no part of the * * SuperNET software, including this file may be copied, modified, propagated * * or distributed except according to the terms contained in the LICENSE file * * * * Removal or modification of this copyright notice is prohibited. * * * ******************************************************************************/ // included from datachain.c #include "datachain_KOMODO.c" #include "datachain_BTC.c" void datachain_events_process_virt(struct supernet_info *myinfo,struct datachain_info *dPoW,struct datachain_event *event) { } int _increasing_events(const void *a,const void *b) { #define uint64_a (*(struct datachain_event **)a)->hdrsi_unspentind #define uint64_b (*(struct datachain_event **)b)->hdrsi_unspentind if ( uint64_b > uint64_a ) return(-1); else if ( uint64_b < uint64_a ) return(1); return(0); #undef uint64_a #undef uint64_b } void datachain_events_sort(struct datachain_info *dPoW) { if ( dPoW->numevents > 0 ) { qsort(dPoW->events,dPoW->numevents,sizeof(dPoW->events),_increasing_events); printf("sorted %d events\n",dPoW->numevents); } } struct datachain_event *datachain_event_create(struct iguana_info *coin,int64_t crypto777_payment,int64_t burned,int32_t height,uint32_t hdrsi,uint32_t unspentind,uint8_t *opreturn,int32_t oplen) { struct datachain_event *event; event = calloc(1,sizeof(*event) + oplen); event->hdrsi_unspentind = ((uint64_t)hdrsi << 32) | unspentind; event->crypto777_payment = crypto777_payment; event->burned = burned; event->height = height; safecopy(event->symbol,coin->symbol,sizeof(event->symbol)); if ( strcmp(event->symbol,"BTC") == 0 ) event->btc_or_btcd = DATACHAIN_ISBTC; else if ( strcmp(event->symbol,"BTCD") == 0 ) event->btc_or_btcd = DATACHAIN_ISKOMODO; event->oplen = oplen; memcpy(event->opreturn,opreturn,oplen); return(event); } void datachain_events_process(struct supernet_info *myinfo,int32_t btc_or_btcd,struct datachain_info *dPoW,int32_t firsti,int32_t lasti) { int32_t i; struct datachain_event *event; if ( firsti >= 0 && lasti <= dPoW->numevents ) { for (i=0; i<=lasti; i++) if ( (event= dPoW->events[i]) != 0 ) { if ( btc_or_btcd == DATACHAIN_ISBTC ) datachain_events_processBTC(myinfo,dPoW,event); else if ( btc_or_btcd == DATACHAIN_ISKOMODO ) datachain_events_processKOMODO(myinfo,dPoW,event); else datachain_events_process_virt(myinfo,dPoW,event); dPoW->state.numprocessed++; } } else printf("illegal datachain_events_process.[%d, %d] numevents.%d\n",firsti,lasti,dPoW->numevents); } void datachain_state_reset(struct supernet_info *myinfo,int32_t btc_or_btcd,struct datachain_info *dPoW) { struct datachain_state *state = &dPoW->state; memset(state,0,sizeof(*state)); } void datachain_reset(struct supernet_info *myinfo,int32_t btc_or_btcd,struct datachain_info *dPoW) { struct iguana_info *virt,*tmp; if ( btc_or_btcd == DATACHAIN_ISBTC ) // all needs to be reset on BTC reorg datachain_reset(myinfo,DATACHAIN_ISKOMODO,&myinfo->dPoW.BTCD); else if ( btc_or_btcd == DATACHAIN_ISKOMODO ) { HASH_ITER(hh,myinfo->allcoins,virt,tmp) { if ( virt->started != 0 && virt->active != 0 && virt->virtualchain != 0 ) datachain_reset(myinfo,0,&virt->dPoW); } } datachain_events_sort(dPoW); datachain_state_reset(myinfo,btc_or_btcd,dPoW); } int32_t datachain_eventadd(struct supernet_info *myinfo,int32_t ordered,struct datachain_info *dPoW,int32_t btc_or_btcd,struct datachain_event *event) { uint64_t hdrsi_unspentind; int32_t retval = 0; if ( ordered != 0 ) { if ( dPoW->ordered == 0 ) datachain_events_sort(dPoW); } else dPoW->ordered = 0; hdrsi_unspentind = ((uint64_t)dPoW->state.lasthdrsi << 32) | dPoW->state.lastunspentind; if ( ordered != 0 ) { if ( dPoW->ordered != dPoW->numevents ) { printf("trigger reset and process.%d ordered.%d numevents.%d\n",btc_or_btcd,dPoW->ordered,dPoW->numevents); datachain_reset(myinfo,btc_or_btcd,dPoW); if ( dPoW->numevents > 0 ) datachain_events_process(myinfo,btc_or_btcd,dPoW,0,dPoW->numevents-1); if ( btc_or_btcd == DATACHAIN_ISBTC ) // all needs to be reprocessed on BTC reorg { if ( myinfo->dPoW.BTCD.numevents > 0 ) datachain_events_process(myinfo,DATACHAIN_ISKOMODO,&myinfo->dPoW.BTCD,0,myinfo->dPoW.BTCD.numevents - 1); } else if ( btc_or_btcd == DATACHAIN_ISKOMODO ) { struct iguana_info *virt,*tmp; HASH_ITER(hh,myinfo->allcoins,virt,tmp) { if ( virt->started != 0 && virt->active != 0 && virt->virtualchain != 0 ) if ( virt->dPoW.numevents > 0 ) datachain_events_process(myinfo,0,&virt->dPoW,0,virt->dPoW.numevents-1); } } dPoW->ordered = dPoW->numevents; } } if ( event != 0 ) { if ( dPoW->numevents >= dPoW->maxevents ) { dPoW->maxevents += 1024; dPoW->events = realloc(dPoW->events,sizeof(*dPoW->events) * dPoW->maxevents); } if ( event->hdrsi_unspentind > hdrsi_unspentind ) { dPoW->state.lasthdrsi = (uint32_t)(event->hdrsi_unspentind >> 32); dPoW->state.lastunspentind = (uint32_t)event->hdrsi_unspentind; retval = 1; } if ( ordered != 0 ) { if ( retval != 1 && dPoW->ordered != 0 ) { printf("datachain_eventadd unexpected ordered event that is not at the end\n"); retval = -1; } dPoW->events[dPoW->numevents] = event; if ( dPoW->ordered == dPoW->numevents ) datachain_events_process(myinfo,btc_or_btcd,dPoW,dPoW->numevents,dPoW->numevents); dPoW->numevents++; dPoW->ordered = dPoW->numevents; } else dPoW->events[dPoW->numevents++] = event; } return(dPoW->numevents); } void datachain_update_txidvout(struct supernet_info *myinfo,int32_t ordered,struct iguana_info *coin,struct datachain_info *dPoW,int32_t btc_or_btcd,int32_t spentheight,bits256 txid,int32_t vout,uint8_t rmd160[20],int64_t value) { // MGW via deposit events }