Encoding is ... */
| 137 | |
| 138 | /* Encoding is <blockhdr> <varint-num-txs> <tx>... */ |
| 139 | struct bitcoin_block * |
| 140 | bitcoin_block_from_hex(const tal_t *ctx, const struct chainparams *chainparams, |
| 141 | const char *hex, size_t hexlen) |
| 142 | { |
| 143 | struct bitcoin_block *b; |
| 144 | u8 *linear_tx; |
| 145 | const u8 *p; |
| 146 | size_t len, i, num, templen; |
| 147 | struct sha256_ctx shactx; |
| 148 | bool is_dynafed; |
| 149 | u32 height; |
| 150 | |
| 151 | if (hexlen && hex[hexlen-1] == '\n') |
| 152 | hexlen--; |
| 153 | |
| 154 | /* Set up the block for success. */ |
| 155 | b = tal(ctx, struct bitcoin_block); |
| 156 | |
| 157 | /* De-hex the array. */ |
| 158 | len = hex_data_size(hexlen); |
| 159 | p = linear_tx = tal_arr(ctx, u8, len); |
| 160 | if (!hex_decode(hex, hexlen, linear_tx, len)) |
| 161 | return tal_free(b); |
| 162 | |
| 163 | sha256_init(&shactx); |
| 164 | |
| 165 | b->hdr.version = pull_le32(&p, &len); |
| 166 | sha256_le32(&shactx, b->hdr.version); |
| 167 | |
| 168 | pull(&p, &len, &b->hdr.prev_hash, sizeof(b->hdr.prev_hash)); |
| 169 | sha256_update(&shactx, &b->hdr.prev_hash, sizeof(b->hdr.prev_hash)); |
| 170 | |
| 171 | pull(&p, &len, &b->hdr.merkle_hash, sizeof(b->hdr.merkle_hash)); |
| 172 | sha256_update(&shactx, &b->hdr.merkle_hash, sizeof(b->hdr.merkle_hash)); |
| 173 | |
| 174 | b->hdr.timestamp = pull_le32(&p, &len); |
| 175 | sha256_le32(&shactx, b->hdr.timestamp); |
| 176 | |
| 177 | if (is_elements(chainparams)) { |
| 178 | /* A dynafed block is signalled by setting the MSB of the version. */ |
| 179 | is_dynafed = (b->hdr.version >> 31 == 1); |
| 180 | |
| 181 | /* elements_header.height */ |
| 182 | height = pull_le32(&p, &len); |
| 183 | sha256_le32(&shactx, height); |
| 184 | |
| 185 | if (is_dynafed) { |
| 186 | bitcoin_block_pull_dynafed_details(&p, &len, &shactx); |
| 187 | } else { |
| 188 | /* elemens_header.challenge */ |
| 189 | templen = pull_varint(&p, &len); |
| 190 | sha256_varint(&shactx, templen); |
| 191 | sha256_update(&shactx, p, templen); |
| 192 | pull(&p, &len, NULL, templen); |
| 193 | |
| 194 | /* elements_header.solution. Not hashed since it'd be |
| 195 | * a circular dependency. */ |
| 196 | templen = pull_varint(&p, &len); |