virtual void edge( uint64_t value, const uint8_t *upTXHash, uint64_t outputIndex, const uint8_t *outputScript, uint64_t outputScriptSize, const uint8_t *downTXHash, uint64_t inputIndex, const uint8_t *inputScript, uint64_t inputScriptSize ) { uint8_t addrType[3]; uint160_t pubKeyHash; int type = solveOutputScript(pubKeyHash.v, outputScript, outputScriptSize, addrType); if(unlikely(type<0)) return; uint64_t a; auto i = addrMap.find(pubKeyHash.v); if(unlikely(addrMap.end()!=i)) a = i->second; else { Addr *addr = (Addr*)allocHash160(); memcpy(addr->v, pubKeyHash.v, kRIPEMD160ByteSize); addrMap[addr->v] = a = allAddrs.size(); allAddrs.push_back(addr); } vertices.push_back(a); }
virtual void wrapup() { size_t size = boost::num_vertices(graph); info( "done, %.2f secs, found %" PRIu64 " address(es) \n", 1e-6*(usecs() - startTime), size ); info("Clustering ... "); startTime = usecs(); std::vector<uint64_t> cc(size); uint64_t nbCC = boost::connected_components(graph, &cc[0]); info( "done, %.2f secs, found %" PRIu64 " clusters.\n", 1e-6*(usecs() - startTime), nbCC ); auto e = rootHashes.end(); auto i = rootHashes.begin(); while(e!=i) { uint64_t count = 0; const uint8_t *keyHash = (i++)->v; uint8_t b58[128]; hash160ToAddr(b58, keyHash); info("Address cluster for address %s:", b58); auto j = addrMap.find(keyHash); if(unlikely(addrMap.end()==j)) { warning("specified key was never used to spend coins"); showFullAddr(keyHash); printf("\n"); count = 1; } else { uint64_t addrIndex = j->second; uint64_t homeComponentIndex = cc[addrIndex]; for(size_t k=0; likely(k<cc.size()); ++k) { uint64_t componentIndex = cc[k]; if(unlikely(homeComponentIndex==componentIndex)) { Addr *addr = allAddrs[k]; showFullAddr(addr->v); printf("\n"); ++count; } } } info("%" PRIu64 " addresse(s)\n", count); } }
void move( const uint8_t *script, uint64_t scriptSize, const uint8_t *txHash, int64_t value, const uint8_t *downTXHash = 0 ) { uint8_t addrType[3]; uint160_t pubKeyHash; int type = solveOutputScript(pubKeyHash.v, script, scriptSize, addrType); if(unlikely(type<0)) return; Addr *addr; auto i = addrMap.find(pubKeyHash.v); if(unlikely(addrMap.end()!=i)) addr = i->second; else { addr = allocAddr(); memcpy(addr->hash.v, pubKeyHash.v, kRIPEMD160ByteSize); addr->sum = 0; addrMap[addr->hash.v] = addr; allAddrs.push_back(addr); } addr->lastTouched = blockTime; addr->sum += value; static uint64_t cnt = 0; if(unlikely(0==((cnt++)&0xFFFFF))) { if( curBlock && lastBlock && firstBlock ) { double progress = curBlock->height/(double)lastBlock->height; info( "%8" PRIu64 " blocks, " "%8.3f MegaMoves , " "%8.3f MegaAddrs , " "%5.2f%%", curBlock->height, cnt*1e-6, addrMap.size()*1e-6, 100.0*progress ); } } }
void move( const uint8_t *script, uint64_t scriptSize, const uint8_t *txHash, uint64_t value, bool add, const uint8_t *downTXHash = 0 ) { uint8_t addrType[3]; uint160_t pubKeyHash; int type = solveOutputScript(pubKeyHash.v, script, scriptSize, addrType); if(unlikely(type<0)) return; bool match = (addrMap.end() != addrMap.find(pubKeyHash.v)); if(unlikely(match)) { int64_t newSum = sum + value*(add ? 1 : -1); if(csv) { printf("%6" PRIu64 ", \"", bTime/86400 + 25569); showHex(pubKeyHash.v, kRIPEMD160ByteSize, false); printf("\", \""); showHex(downTXHash ? downTXHash : txHash); printf( "\",%17.08f,%17.08f\n", (add ? 1e-8 : -1e-8)*value, newSum*1e-8 ); } else { struct tm gmTime; time_t blockTime = bTime; gmtime_r(&blockTime, &gmTime); char timeBuf[256]; asctime_r(&gmTime, timeBuf); size_t sz =strlen(timeBuf); if(0<sz) timeBuf[sz-1] = 0; printf(" %s ", timeBuf); showHex(pubKeyHash.v, kRIPEMD160ByteSize, false); printf(" "); showHex(downTXHash ? downTXHash : txHash); printf( " %24.08f %c %24.08f = %24.08f\n", sum*1e-8, add ? '+' : '-', value*1e-8, newSum*1e-8 ); } (add ? adds : subs) += value; sum = newSum; ++nbTX; } }
void move( const uint8_t *script, uint64_t scriptSize, const uint8_t *upTXHash, int64_t outputIndex, int64_t value, const uint8_t *downTXHash = 0, uint64_t inputIndex = -1 ) { uint8_t addrType[3]; uint160_t pubKeyHash; int type = solveOutputScript(pubKeyHash.v, script, scriptSize, addrType); if(unlikely(type<0)) return; if(0!=restrictMap.size()) { auto r = restrictMap.find(pubKeyHash.v); if(restrictMap.end()==r) { return; } } Addr *addr; auto i = addrMap.find(pubKeyHash.v); if(unlikely(addrMap.end()!=i)) { addr = i->second; } else { addr = allocAddr(); memcpy(addr->hash.v, pubKeyHash.v, kRIPEMD160ByteSize); addr->outputVec = 0; addr->nbOut = 0; addr->nbIn = 0; addr->sum = 0; if(detailed) { addr->outputVec = new OutputVec; } addrMap[addr->hash.v] = addr; allAddrs.push_back(addr); } if(0<value) { addr->lastIn = blockTime; ++(addr->nbIn); } else { addr->lastOut = blockTime; ++(addr->nbOut); } addr->sum += value; if(detailed) { struct Output output; output.value = value; output.time = blockTime; output.upTXHash = upTXHash; output.downTXHash = downTXHash; output.inputIndex = inputIndex; output.outputIndex = outputIndex; addr->outputVec->push_back(output); } }