// 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; } // A bitcoin output message bitcoin_output { required uint64 amount = 1; required bytes script = 2; } // Pubkey for commitment transaction input. message bitcoin_pubkey { // Either 65 or 33 bytes. required bytes key = 1; }; // 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 bitcoin_output 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 to_me = 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; // Signature for new commitment tx. required signature sig = 3; // Signature for old anchor (if any) optional signature old_anchor_sig = 4; // FIXME: optional HTLC ops. } // OK, I accept that update. message update_accept { // Signature for 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; // Hash preimage which revokes old commitment tx. required sha256_hash revocation_preimage = 4; } // 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->script_to_me and your open->script_to_me, // 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_complete update_complete = 3; // 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; } }