Pkt *accept_pkt_htlc_fulfill(struct peer *peer, const Pkt *pkt) { const UpdateFulfillHtlc *f = pkt->update_fulfill_htlc; size_t n_us, n_them; struct sha256 r, rhash; Pkt *err; err = find_commited_htlc(peer, f->id, &n_us, &n_them); if (err) return err; /* Now, it must solve the HTLC rhash puzzle. */ proto_to_sha256(f->r, &r); sha256(&rhash, &r, sizeof(r)); if (!structeq(&rhash, &peer->us.staging_cstate->a.htlcs[n_us].rhash)) return pkt_err(peer, "Invalid r for %"PRIu64, f->id); /* Same ID must have same rhash */ assert(structeq(&rhash, &peer->them.staging_cstate->b.htlcs[n_them].rhash)); funding_a_fulfill_htlc(peer->us.staging_cstate, n_us); funding_b_fulfill_htlc(peer->them.staging_cstate, n_them); return NULL; }
static bool check_preimage(const Sha256Hash *preimage, const struct sha256 *hash) { struct sha256 h; proto_to_sha256(preimage, &h); sha256(&h, &h, sizeof(h)); return structeq(&h, hash); }
bool check_proof_byhash(const struct protocol_proof *proof, const struct block *b, const struct protocol_txrefhash *txrefhash) { struct protocol_double_sha merkle; u16 shardnum = le16_to_cpu(proof->pos.shard); assert(structeq(&b->sha, &proof->pos.block)); /* Can't be right if shard doesn't exist. */ if (shardnum >= (1 << b->hdr->shard_order)) return false; /* Can't be the right one if not within shard */ if (proof->pos.txoff >= b->shard_nums[shardnum]) return false; proof_merkles_to(txrefhash, proof, &merkle); return structeq(&b->merkles[shardnum], &merkle); }
u32 find_matching_input(const union protocol_tx *tx, const struct protocol_input *inp) { unsigned int i; /* Figure out which input of other did the spend. */ for (i = 0; i < num_inputs(tx); i++) { if (structeq(&tx_input(tx, i)->input, &inp->input) && tx_input(tx, i)->output == inp->output) return i; } abort(); }
static void check_preimage(const Sha256Hash *preimage, const struct sha256 *old, const struct sha256 *h, const char *file) { struct sha256 sha; if (!h) return; proto_to_sha256(preimage, &sha); sha256(&sha, &sha, sizeof(sha)); if (!structeq(&sha, old)) errx(1, "Invalid preimage in %s!", file); }
enum ref_ecode check_tx_refs(struct state *state, const struct block *block, const union protocol_tx *tx, const struct protocol_input_ref *refs, unsigned int *bad_ref, struct block **block_referred_to) { unsigned int i, num = num_inputs(tx); bool all_known = true; assert(check_refs(state, block, refs, num) == PROTOCOL_ECODE_NONE); for (i = 0; i < num; i++) { struct block *b; struct protocol_txrefhash scratch; const struct protocol_txrefhash *txp; b = block_ancestor(block, le32_to_cpu(refs[i].blocks_ago)); txp = txrefhash_in_shard(b->shard[le16_to_cpu(refs[i].shard)], refs[i].txoff, &scratch); if (!txp) { *bad_ref = i; *block_referred_to = b; all_known = false; /* Keep looking in case there are worse issues. */ continue; } if (!structeq(&txp->txhash, &tx_input(tx, i)->input)) { *bad_ref = i; *block_referred_to = b; return ECODE_REF_BAD_HASH; } } if (!all_known) return ECODE_REF_UNKNOWN; return ECODE_REF_OK; }
Pkt *accept_pkt_htlc_fulfill(struct peer *peer, const Pkt *pkt) { const UpdateFulfillHtlc *f = pkt->update_fulfill_htlc; struct htlc *htlc; struct sha256 rhash; struct rval r; Pkt *err; union htlc_staging stage; err = find_commited_htlc(peer, f->id, &htlc); if (err) return err; /* Now, it must solve the HTLC rhash puzzle. */ proto_to_rval(f->r, &r); sha256(&rhash, &r, sizeof(r)); if (!structeq(&rhash, &htlc->rhash)) return pkt_err(peer, "Invalid r for %"PRIu64, f->id); /* We can relay this upstream immediately. */ our_htlc_fulfilled(peer, htlc, &r); /* BOLT #2: * * ... and the receiving node MUST add the HTLC fulfill/fail * to the unacked changeset for its local commitment. */ cstate_fulfill_htlc(peer->local.staging_cstate, htlc, OURS); stage.fulfill.fulfill = HTLC_FULFILL; stage.fulfill.htlc = htlc; stage.fulfill.r = r; add_unacked(&peer->local, &stage); return NULL; }
int main(void) { void *ctx = tal(NULL, char); char *p; bool test_net; struct protocol_address addr, addr2; struct protocol_pubkey pubkey, pubkey2; EC_KEY *key; memset(&addr, 0xFF, sizeof(addr)); /* Normal net */ p = pettycoin_to_base58(ctx, false, &addr, false); assert(tal_parent(p) == ctx); assert(p[0] == 'P'); assert(strlen(p) < BASE58_ADDR_MAX_LEN); assert(strspn(p, enc) == strlen(p)); memset(&addr2, 0, sizeof(addr2)); assert(pettycoin_from_base58(&test_net, &addr2, p, strlen(p))); assert(test_net == false); assert(structeq(&addr, &addr2)); /* Test net */ p = pettycoin_to_base58(ctx, true, &addr, false); assert(tal_parent(p) == ctx); assert(p[0] == 'q'); assert(strlen(p) < BASE58_ADDR_MAX_LEN); assert(strspn(p, enc) == strlen(p)); memset(&addr2, 0, sizeof(addr2)); assert(pettycoin_from_base58(&test_net, &addr2, p, strlen(p))); assert(test_net == true); assert(structeq(&addr, &addr2)); /* Bitcoin-style, normal net */ p = pettycoin_to_base58(ctx, false, &addr, true); assert(tal_parent(p) == ctx); assert(strstarts(p, "P-1")); assert(strlen(p) < BASE58_ADDR_MAX_LEN + 2); assert(strspn(p+2, enc) == strlen(p+2)); memset(&addr2, 0, sizeof(addr2)); assert(pettycoin_from_base58(&test_net, &addr2, p, strlen(p))); assert(test_net == false); assert(structeq(&addr, &addr2)); /* Bitcoin-style, test net */ p = pettycoin_to_base58(ctx, true, &addr, true); assert(tal_parent(p) == ctx); assert(strstarts(p, "P-m") || strstarts(p, "P-n")); assert(strlen(p) < BASE58_ADDR_MAX_LEN + 2); assert(strspn(p+2, enc) == strlen(p+2)); memset(&addr2, 0, sizeof(addr2)); assert(pettycoin_from_base58(&test_net, &addr2, p, strlen(p))); assert(test_net == true); assert(structeq(&addr, &addr2)); /* From our test gateway key */ key = key_from_base58("P-cRhETWFwVpi7q8Vjs7KqvYYGZC5htvT3ddnd9hJk5znSohTBHRkT", strlen("P-cRhETWFwVpi7q8Vjs7KqvYYGZC5htvT3ddnd9hJk5znSohTBHRkT"), &test_net, &pubkey); assert(key); assert(test_net == true); /* Check pubkey is correct. */ pubkey_to_addr(&pubkey, &addr); p = pettycoin_to_base58(ctx, true, &addr, true); assert(streq(p, "P-muzRJJzenB7uKzokx21W2QGobfDEZfiH1u")); /* Check we can return it OK (bitcoin style) */ p = key_to_base58(ctx, true, key, true); assert(streq(p, "P-cRhETWFwVpi7q8Vjs7KqvYYGZC5htvT3ddnd9hJk5znSohTBHRkT")); /* Now, turn it into pettcoin-style key. */ p = key_to_base58(ctx, true, key, false); assert(strspn(p, enc) == strlen(p)); /* Convert back, check it is OK. */ EC_KEY_free(key); key = key_from_base58(p, strlen(p), &test_net, &pubkey2); assert(key); assert(test_net == true); assert(structeq(&pubkey, &pubkey2)); EC_KEY_free(key); /* FIXME: Test non-test network keys! */ tal_free(ctx); return 0; }
bool txwatch_eq(const struct txwatch *w, const struct sha256_double *txid) { return structeq(&w->txid, txid); }
bool txowatch_eq(const struct txowatch *w, const struct txwatch_output *out) { return structeq(&w->out.txid, &out->txid) && w->out.index == out->index; }