core-lightning/lightning.proto
Rusty Russell ed3f0115d6 protocol: fix horribly thinko, keep own secrets.
I had each side using the other side's hash secret.  That's a very
dumb idea, since it means you can steal from a unilateral close!

A's secret applies to A's commit transaction: it needs the
secret and B's final signature to steal funds, and that should
never happen (since A doesn't have the B's final signature, and
once A has given B the secret, they never broadcast the commit tx).

This makes the update a 4 step dance, since you need the new
revocation hash to make the other side's TX to sign.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2015-06-10 21:39:45 +09:30

224 lines
6.3 KiB
Protocol Buffer

// The outer layer handles encryption, authentication and message
// boundaries.
//
// Helper Types
//
// Protobufs don't have fixed-length fields, so these are a hack.
message sha256_hash {
required fixed64 a = 1;
required fixed64 b = 2;
required fixed64 c = 3;
required fixed64 d = 4;
}
message signature {
required fixed64 r1 = 1;
required fixed64 r2 = 2;
required fixed64 r3 = 3;
required fixed64 r4 = 4;
required fixed64 s1 = 5;
required fixed64 s2 = 6;
required fixed64 s3 = 7;
required fixed64 s4 = 8;
}
// Identifies consumption of a bitcoin output.
message bitcoin_input {
// This is the transaction ID.
required sha256_hash txid = 1;
// This is the output number.
required uint32 output = 2;
// And the subscript we're signing.
required bytes subscript = 3;
// The amount this input is worth.
required uint64 amount = 4;
}
// Pubkey for commitment transaction input.
message bitcoin_pubkey {
// Either 65 or 33 bytes.
required bytes key = 1;
};
// Change, if we want any.
message change {
required uint64 amount = 1;
required bitcoin_pubkey pubkey = 2;
}
// All about an anchor transaction.
message anchor {
// 0 or more unspent inputs we want to use for anchor.
repeated bitcoin_input inputs = 1;
// Pubkey for anchor to pay to for commitment tx (p2sh)
required bitcoin_pubkey pubkey = 5;
// Any change from anchor (in case we don't want to use them all)
optional change change = 2;
// How much transaction fee we'll pay in the anchor tx.
required uint64 fee = 8;
// How much we'll be putting into channel (== sum(inputs) - change - fee)
required uint64 total = 4;
// How many confirmations on anchor before we'll use channel.
required uint32 min_confirms = 10;
}
//
// Packet Types
//
// Set channel params.
message open_channel {
// Seed which sets order we create outputs for all transactions.
required uint64 seed = 1;
// Relative locktime for outputs going to us.
required uint32 locktime_seconds = 2;
// Hash seed for revoking commitment transactions.
required sha256_hash revocation_hash = 4;
// How to pay money to us from commit_tx.
required bitcoin_pubkey final = 5;
// How much transaction fee we'll pay for commitment txs.
required uint64 commitment_fee = 6;
// The anchor transaction details.
required anchor anchor = 7;
// Maximum transaction version we support.
required uint32 tx_version = 8;
}
// Supply signature for commitment tx
message open_commit_sig {
required signature sig = 1;
}
// Supply ScriptSig for each anchor tx inputs.
message open_anchor_scriptsigs {
repeated bytes script = 1;
}
// BROKEN AND INSECURE!!!
//
// This should not exist; it's completely insecure! But we need to sign
// the commitment transaction before we sign the anchor transaction, which
// doesn't work at all with current bitcoin (as we don't know the anchor
// txid until it's signed by both sides, and then we'd have to worry about
// malleability anyway). So for testing, we send the scriptsigs for the
// anchor transaction's inputs immediately.
message leak_anchor_sigs_and_pretend_we_didnt {
required open_anchor_scriptsigs sigs = 1;
}
// Indicates we've seen transaction reach min-depth.
message open_complete {
// Block it went into.
optional sha256_hash blockid = 1;
// FIXME: add a merkle proof plus block headers here?
}
// Let's spend some money in the channel!
message update {
// Hash for which I will supply preimage to revoke this.
required sha256_hash revocation_hash = 1;
// Change in current payment to-me (implies reverse to-you).
required sint64 delta = 2;
// FIXME: optional HTLC ops.
}
// OK, I accept that update; here's your signature.
message update_accept {
// Signature for your new commitment tx.
required signature sig = 1;
// Signature for old anchor (if any)
optional signature old_anchor_sig = 2;
// Hash for which I will supply preimage to revoke this new commit tx.
required sha256_hash revocation_hash = 3;
}
// Thanks for accepting, here's my last bit.
message update_signature {
// Signature for your new commitment tx.
required signature sig = 1;
// Hash preimage which revokes old commitment tx.
required sha256_hash revocation_preimage = 2;
}
// Complete the update.
message update_complete {
// Hash preimage which revokes old commitment tx.
required sha256_hash revocation_preimage = 1;
}
// Let's change the channel funding source.
message new_anchor {
// The new anchor: previous anchor 2x2 input assumed.
required anchor anchor = 1;
}
// That seems OK to me, let's add these too (if any).
message new_anchor_ack {
required anchor anchor = 1;
}
// Now we both send signatures for new commit sig.
message new_anchor_commit_sig {
required signature sig = 1;
}
// Here are the script sigs for the new anchor's new inputs.
message new_anchor_accept {
repeated bytes script = 1;
}
// Complete the transfer to new anchor (both ends need to send this,
// once they're happy that it's reached their required depth).
message new_anchor_complete {
required sha256_hash revocation_preimage = 1;
}
// Begin cooperative close of channel.
message close_channel {
// This is our signature a new transaction which spends the anchor
// output to my open->final and your open->final,
// as per the last commit tx.
required signature sig = 1;
}
// OK, here's my sig so you can broadcast it too. We're done.
message close_channel_complete {
// This is my signature for that same tx.
required signature sig = 1;
}
// This means we're going to hang up; it's to help diagnose only!
message error {
optional string problem = 1;
}
// This is the union which defines all of them
message pkt {
oneof pkt {
// Opening
open_channel open = 201;
leak_anchor_sigs_and_pretend_we_didnt omg_fail = 205;
open_commit_sig open_commit_sig = 202;
open_anchor_scriptsigs open_anchor_scriptsigs = 203;
open_complete open_complete = 204;
// Updating (most common)
update update = 1;
update_accept update_accept = 2;
update_signature update_signature = 3;
update_complete update_complete = 4;
// Topping up
new_anchor new_anchor = 301;
new_anchor_ack new_anchor_ack = 302;
new_anchor_accept new_anchor_accept = 303;
new_anchor_complete new_anchor_complete = 304;
// Closing
close_channel close = 401;
close_channel_complete close_complete = 402;
// Unexpected issue.
error error = 1000;
}
}