/* This allocates the block but doesn't sew it into data structures. */ static struct block *new_block(const tal_t *ctx, BIGNUM *prev_work, const struct protocol_block_id *sha, const struct block_info *bi) { struct block *block = tal(ctx, struct block); unsigned int i; total_work_done(le32_to_cpu(bi->tailer->difficulty), prev_work, &block->total_work); block->bi = *bi; block->all_known = false; list_head_init(&block->children); block->sha = *sha; block->shard = tal_arr(block, struct block_shard *, num_shards(bi->hdr)); for (i = 0; i < num_shards(bi->hdr); i++) block->shard[i] = new_block_shard(block->shard, i, bi->num_txs[i]); /* In case we destroy before block_add(), eg. testing. */ block->prev = NULL; tal_add_destructor(block, destroy_block); return block; }
/** * Returns the number of edges in the graph. * This may be slow. */ inline uint64_t num_edges() const { size_t ret = 0; for (size_t i = 0; i < num_shards(); i++) { ret += shardarr[i].num_edges(); } return ret; }
/* Transfer all transaction from this block into pending array */ void block_to_pending(struct state *state, const struct block *block) { unsigned int shard, i; for (shard = 0; shard < num_shards(block->hdr); shard++) { for (i = 0; i < block->shard_nums[shard]; i++) { const union protocol_tx *tx; tx = tx_for(block->shard[shard], i); if (!tx) continue; /* recheck_pending_txs() will sort it out */ add_to_unknown_pending(state, tx); state->pending->needs_recheck = true; } } }
static enum protocol_ecode check_ref(struct state *state, const struct block *block, const struct protocol_input_ref *ref) { struct block *b = block_ancestor(block, le32_to_cpu(ref->blocks_ago)); if (!b) return PROTOCOL_ECODE_REF_BAD_BLOCKS_AGO; /* Beyond horizon? */ if (le32_to_cpu(b->tailer->timestamp) + PROTOCOL_TX_HORIZON_SECS(state->test_net) < le32_to_cpu(block->tailer->timestamp)) return PROTOCOL_ECODE_REF_BAD_BLOCKS_AGO; if (le16_to_cpu(ref->shard) >= num_shards(b->hdr)) return PROTOCOL_ECODE_REF_BAD_SHARD; if (ref->txoff >= b->shard_nums[le16_to_cpu(ref->shard)]) return PROTOCOL_ECODE_REF_BAD_TXOFF; return PROTOCOL_ECODE_NONE; }
static void complaint_on_all(struct state *state, struct block *block, const void *complaint) { struct block *b; unsigned int shard, txoff; /* Mark block. */ block->complaint = complaint; /* Can we salvage any txs? */ block_to_pending(state, block); /* Remove transactions, and maybe inputs. */ for (shard = 0; shard < num_shards(block->hdr); shard++) { for (txoff = 0; txoff < block->shard[shard]->size; txoff++) { remove_tx_from_hashes(state, block, shard, txoff); } } /* Mark descendents. */ list_for_each(&block->children, b, sibling) complaint_on_all(state, b, complaint); }