// testNewestShaEmpty ensures the NewestSha returns the values expected by // the interface contract. func testNewestShaEmpty(t *testing.T, db btcdb.Db) { sha, height, err := db.NewestSha() if err != nil { t.Errorf("NewestSha error %v", err) } if !sha.IsEqual(&zeroHash) { t.Errorf("NewestSha wrong hash got: %s, want %s", sha, &zeroHash) } if height != -1 { t.Errorf("NewestSha wrong height got: %d, want %d", height, -1) } }
func testNewestSha(t *testing.T, db btcdb.Db, expSha btcwire.ShaHash, expBlk int64, situation string) { newestsha, blkid, err := db.NewestSha() if err != nil { t.Errorf("NewestSha failed %v (%s)", err, situation) return } if blkid != expBlk { t.Errorf("NewestSha blkid is %d not %d (%s)", blkid, expBlk, situation) } if !newestsha.IsEqual(&expSha) { t.Errorf("Newestsha isn't the last sha we inserted %v %v (%s)", newestsha, &expSha, situation) } }
func verifyChain(db btcdb.Db, level, depth int32) error { _, curheight64, err := db.NewestSha() if err != nil { rpcsLog.Errorf("Verify is unable to fetch current block "+ "height: %v", err) } curheight := int32(curheight64) if depth > curheight { depth = curheight } for height := curheight; height > (curheight - depth); height-- { // Level 0 just looks up the block. sha, err := db.FetchBlockShaByHeight(int64(height)) if err != nil { rpcsLog.Errorf("Verify is unable to fetch block at "+ "height %d: %v", height, err) return err } block, err := db.FetchBlockBySha(sha) if err != nil { rpcsLog.Errorf("Verify is unable to fetch block at "+ "sha %v height %d: %v", sha, height, err) return err } // Level 1 does basic chain sanity checks. if level > 0 { err := btcchain.CheckBlockSanity(block, activeNetParams.powLimit) if err != nil { rpcsLog.Errorf("Verify is unable to "+ "validate block at sha %v height "+ "%d: %v", sha, height, err) return err } } } rpcsLog.Infof("Chain verify completed successfully") return nil }
func search(log btclog.Logger, db btcdb.Db) map[string][]*rData { // Setup signal handler signalChan := make(chan os.Signal, 1) signal.Notify(signalChan, syscall.SIGINT, syscall.SIGTERM, syscall.SIGUSR1) // Potential optimisation: keep the bloom filter between runs filter := dablooms.NewScalingBloom(bloomSize, bloomRate, "blockchainr_bloom.bin") if filter == nil { log.Warn("dablooms.NewScalingBloom failed") return nil } potentialValues := make(stringSet) rMap := make(map[string][]*rData) _, maxHeigth, err := db.NewestSha() if err != nil { log.Warnf("db NewestSha failed: %v", err) return nil } for step := 1; step <= 2; step++ { lastTime := time.Now() lastSig := int64(0) sigCounter := int64(0) matches := int64(0) ticker := time.Tick(tickFreq * time.Second) signatures := getSignatures(maxHeigth, log, db) for rd := range signatures { select { case s := <-signalChan: log.Infof("Step %v - signal %v - %v sigs in %.2fs, %v matches, %v total, block %v of %v", step, s, sigCounter-lastSig, time.Since(lastTime).Seconds(), matches, sigCounter, rd.H, maxHeigth) if s == syscall.SIGINT || s == syscall.SIGTERM { return rMap } case <-ticker: log.Infof("Step %v - %v sigs in %.2fs, %v matches, %v total, block %v of %v", step, sigCounter-lastSig, time.Since(lastTime).Seconds(), matches, sigCounter, rd.H, maxHeigth) lastTime = time.Now() lastSig = sigCounter default: break } // Potential optimisation: store in potentialValues also the block // height, and if step 2 finds the same h first, it's a bloom // false positive if step == 1 { b := rd.sig.R.Bytes() if filter.Check(b) { matches++ potentialValues.Add(rd.sig.R.String()) } else { if !filter.Add(b, 1) { log.Warn("Add failed (?)") } } } else if step == 2 { if potentialValues.Contains(rd.sig.R.String()) { matches++ rMap[rd.sig.R.String()] = append(rMap[rd.sig.R.String()], rd) } } sigCounter++ } if *memprofile != "" { f, err := os.Create(fmt.Sprintf("%s.%d", *memprofile, step)) if err != nil { log.Warnf("open memprofile failed: %v", err) return nil } pprof.WriteHeapProfile(f) f.Close() } log.Infof("Step %v done - %v signatures processed - %v matches", step, sigCounter, matches) } return rMap }