func json_system(w http.ResponseWriter, r *http.Request) { if !ipchecker(r) { return } var out struct { Blocks_cached int BlocksToGet int Known_peers int Node_uptime uint64 Net_block_qsize int Net_tx_qsize int Heap_size uint64 Heap_sysmem uint64 Qdb_extramem int64 Ecdsa_verify_cnt uint64 Average_block_size uint Average_fee float64 LastHeaderHeight uint32 } out.Blocks_cached = len(network.CachedBlocks) out.BlocksToGet = len(network.BlocksToGet) out.Known_peers = peersdb.PeerDB.Count() out.Node_uptime = uint64(time.Now().Sub(common.StartTime).Seconds()) out.Net_block_qsize = len(network.NetBlocks) out.Net_tx_qsize = len(network.NetTxs) out.Heap_size, out.Heap_sysmem = sys.MemUsed() out.Qdb_extramem = qdb.ExtraMemoryConsumed out.Ecdsa_verify_cnt = btc.EcdsaVerifyCnt out.Average_block_size = common.GetAverageBlockSize() out.Average_fee = common.GetAverageFee() network.MutexRcv.Lock() out.LastHeaderHeight = network.LastCommitedHeader.Height network.MutexRcv.Unlock() bx, er := json.Marshal(out) if er == nil { w.Header()["Content-Type"] = []string{"application/json"} w.Write(bx) } else { println(er.Error()) } }
func (c *OneConnection) GetBlockData() (yes bool) { //MAX_GETDATA_FORWARD // Need to send getdata...? MutexRcv.Lock() defer MutexRcv.Unlock() if LowestIndexToBlocksToGet == 0 || len(BlocksToGet) == 0 { c.IncCnt("FetchNoBlocksToGet", 1) // wake up in one minute, just in case c.nextGetData = time.Now().Add(60 * time.Second) return } cbip := c.BlksInProgress() if cbip >= MAX_PEERS_BLOCKS_IN_PROGRESS { c.IncCnt("FetchMaxCountInProgress", 1) // wake up in a few seconds, maybe some blocks will complete by then c.nextGetData = time.Now().Add(5 * time.Second) return } avg_block_size := int(common.GetAverageBlockSize()) block_data_in_progress := cbip * avg_block_size if block_data_in_progress+avg_block_size > MAX_GETDATA_FORWARD { c.IncCnt("FetchMaxBytesInProgress", 1) // wake up in a few seconds, maybe some blocks will complete by then c.nextGetData = time.Now().Add(5 * time.Second) // wait for some blocks to complete return } var cnt uint64 var block_type uint32 if (c.Node.Services & SERVICE_SEGWIT) != 0 { block_type = MSG_WITNESS_BLOCK } else { block_type = MSG_BLOCK } // We can issue getdata for this peer // Let's look for the lowest height block in BlocksToGet that isn't being downloaded yet common.Last.Mutex.Lock() max_height := common.Last.Block.Height + uint32(MAX_BLOCKS_FORWARD_SIZ/avg_block_size) if max_height > common.Last.Block.Height+MAX_BLOCKS_FORWARD_CNT { max_height = common.Last.Block.Height + MAX_BLOCKS_FORWARD_CNT } common.Last.Mutex.Unlock() if max_height > c.Node.Height { max_height = c.Node.Height } if max_height > LastCommitedHeader.Height { max_height = LastCommitedHeader.Height } if common.BlockChain.Consensus.Enforce_SEGWIT != 0 && (c.Node.Services&SERVICE_SEGWIT) == 0 { // no segwit node if max_height >= common.BlockChain.Consensus.Enforce_SEGWIT-1 { max_height = common.BlockChain.Consensus.Enforce_SEGWIT - 1 if max_height <= common.Last.Block.Height { c.IncCnt("FetchNoWitness", 1) c.nextGetData = time.Now().Add(3600 * time.Second) // never do getdata return } } } invs := new(bytes.Buffer) var cnt_in_progress uint for { var lowest_found *OneBlockToGet // Get block to fetch: for bh := LowestIndexToBlocksToGet; bh <= max_height; bh++ { if idxlst, ok := IndexToBlocksToGet[bh]; ok { for _, idx := range idxlst { v := BlocksToGet[idx] if v.InProgress == cnt_in_progress && (lowest_found == nil || v.Block.Height < lowest_found.Block.Height) { c.Mutex.Lock() if _, ok := c.GetBlockInProgress[idx]; !ok { lowest_found = v } c.Mutex.Unlock() } } } } if lowest_found == nil { cnt_in_progress++ if cnt_in_progress >= uint(common.CFG.Net.MaxBlockAtOnce) { break } continue } binary.Write(invs, binary.LittleEndian, block_type) invs.Write(lowest_found.BlockHash.Hash[:]) lowest_found.InProgress++ cnt++ c.Mutex.Lock() c.GetBlockInProgress[lowest_found.BlockHash.BIdx()] = &oneBlockDl{hash: lowest_found.BlockHash, start: time.Now()} cbip = len(c.GetBlockInProgress) c.Mutex.Unlock() if cbip >= MAX_PEERS_BLOCKS_IN_PROGRESS { break // no more than 2000 blocks in progress / peer } block_data_in_progress += avg_block_size if block_data_in_progress > MAX_GETDATA_FORWARD { break } } if cnt == 0 { //println(c.ConnID, "fetch nothing", cbip, block_data_in_progress, max_height-common.Last.Block.Height, cnt_in_progress) c.IncCnt("FetchNothing", 1) // wake up in a few seconds, maybe it will be different next time c.nextGetData = time.Now().Add(5 * time.Second) return } bu := new(bytes.Buffer) btc.WriteVlen(bu, uint64(cnt)) pl := append(bu.Bytes(), invs.Bytes()...) //println(c.ConnID, "fetching", cnt, "new blocks ->", cbip) c.SendRawMsg("getdata", pl) yes = true return }