int main(void) { struct sha256 seed; struct shachain chain; struct sha256 expect[NUM_TESTS]; size_t i, j; /* This is how many tests you plan to run */ plan_tests(NUM_TESTS * 3 + NUM_TESTS * (NUM_TESTS + 1)); memset(&seed, 0, sizeof(seed)); /* Generate a whole heap. */ for (i = 0; i < NUM_TESTS; i++) { shachain_from_seed(&seed, i, &expect[i]); if (i == 0) ok1(memcmp(&expect[i], &seed, sizeof(expect[i]))); else ok1(memcmp(&expect[i], &expect[i-1], sizeof(expect[i]))); } shachain_init(&chain); for (i = 0; i < NUM_TESTS; i++) { struct sha256 hash; ok1(shachain_add_hash(&chain, i, &expect[i])); for (j = 0; j <= i; j++) { ok1(shachain_get_hash(&chain, j, &hash)); ok1(memcmp(&hash, &expect[j], sizeof(hash)) == 0); } ok1(!shachain_get_hash(&chain, i+1, &hash)); } return exit_status(); }
Pkt *accept_pkt_revocation(struct peer *peer, const Pkt *pkt) { const UpdateRevocation *r = pkt->update_revocation; struct commit_info *ci = peer->remote.commit->prev; /* BOLT #2: * * The receiver of `update_revocation` MUST check that the * SHA256 hash of `revocation_preimage` matches the previous commitment * transaction, and MUST fail if it does not. */ if (!check_preimage(r->revocation_preimage, &ci->revocation_hash)) return pkt_err(peer, "complete preimage incorrect"); /* They're revoking the previous one. */ assert(!ci->revocation_preimage); ci->revocation_preimage = tal(ci, struct sha256); proto_to_sha256(r->revocation_preimage, ci->revocation_preimage); // save revocation preimages in shachain if (!shachain_add_hash(&peer->their_preimages, 0xFFFFFFFFFFFFFFFFL - ci->commit_num, ci->revocation_preimage)) return pkt_err(peer, "preimage not next in shachain"); /* Save next revocation hash. */ proto_to_sha256(r->next_revocation_hash, &peer->remote.next_revocation_hash); /* BOLT #2: * * The receiver of `update_revocation`... MUST add the remote * unacked changes to the set of local acked changes. */ add_acked_changes(&peer->local.commit->acked_changes, ci->unacked_changes); apply_changeset(peer, &peer->local, OURS, ci->unacked_changes, tal_count(ci->unacked_changes)); /* Should never examine these again. */ ci->unacked_changes = tal_free(ci->unacked_changes); /* That revocation has committed them to changes in the current commitment. * Any acked changes come from our commitment, so those are now committed * by both of us. */ peer_both_committed_to(peer, ci->acked_changes, THEIRS); return NULL; }