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; }
int main(int argc, char *argv[]) { unsigned long long tps, tsize, trans_per_block, merkles_per_block, blocksize, shard_order, txbytes_per_sec, blockbytes_per_sec; if (argc != 2) errx(1, "Usage: sizes <tps>"); tps = atoi(argv[1]); tsize = sizeof(struct protocol_tx_normal) + sizeof(struct protocol_input) * AVERAGE_INPUTS; printf("# Assuming %f average inputs => tsize %llu bytes\n", AVERAGE_INPUTS, tsize); trans_per_block = tps * PROTOCOL_BLOCK_TARGET_TIME(false); printf("Transactions per block: %llu\n", trans_per_block); /* Increase shard order until shards are half full. */ for (shard_order = PROTOCOL_INITIAL_SHARD_ORDER; (128 << shard_order) < trans_per_block; shard_order++); printf("Shards: (2^%llu) %llu\n", shard_order, 1ULL << shard_order); if (shard_order > 16) { printf("*** Truncating shards to 2^16 (need u32 shardnum!)\n"); shard_order = 16; } merkles_per_block = (1 << shard_order); blocksize = sizeof(struct protocol_block_header) + merkles_per_block * sizeof(struct protocol_double_sha) + merkles_per_block * PROTOCOL_PREV_BLOCK_TXHASHES + sizeof(struct protocol_block_tailer); printf("Block size: %llu\n", blocksize); txbytes_per_sec = tps * tsize; blockbytes_per_sec = blocksize / PROTOCOL_BLOCK_TARGET_TIME(false); printf("%-15s%15s%15s%15s %s\n", "", "Transactions", "Blocks", "Total", "Units"); /* Miners need every transaction + every block. */ printf("%-15s%15llu%15llu%15llu %s\n", "Miners pipe", txbytes_per_sec, blockbytes_per_sec, txbytes_per_sec + blockbytes_per_sec, "bytes per second"); printf("%-15s%15llu%15llu%25s\n", "Miners storage", txbytes_per_sec * PROTOCOL_TX_HORIZON_SECS(false), blockbytes_per_sec * PROTOCOL_TX_HORIZON_SECS(false), format_si(txbytes_per_sec * PROTOCOL_TX_HORIZON_SECS(false) + blockbytes_per_sec * PROTOCOL_TX_HORIZON_SECS(false))); /* Minimal node needs two shards + every block. */ txbytes_per_sec >>= shard_order - 1; printf("%-15s%15llu%15llu%15llu %s\n", "Minimal pipe", txbytes_per_sec, blockbytes_per_sec, txbytes_per_sec + blockbytes_per_sec, "bytes per second"); printf("%-15s%15llu%15llu%25s\n", "Minimal storage", txbytes_per_sec * PROTOCOL_TX_HORIZON_SECS(false), blockbytes_per_sec * PROTOCOL_TX_HORIZON_SECS(false), format_si(txbytes_per_sec * PROTOCOL_TX_HORIZON_SECS(false) + blockbytes_per_sec * PROTOCOL_TX_HORIZON_SECS(false))); return 0; }
/* When do transactions in this block expire? */ u32 block_expiry(struct state *state, const struct block_info *bi) { return block_timestamp(bi) + PROTOCOL_TX_HORIZON_SECS(state->test_net); }