lnwallet: encode obfuscated state hints in the commitment tx

This commit modifies the channel state machine slightly to encode the
current state number using 30-bits of the sequence number within the
commitment transaction’s only input.

Such a modification reduces up the processing time required to punish
the counter party for breaching the contract established within the
channel by broadcasting an older revoked state.

This fixes #58 with a minor modification to what was originally
suggested.
This commit is contained in:
Olaoluwa Osuntokun 2016-11-16 12:49:37 -08:00
parent e44b2b91fc
commit 74122a0901
No known key found for this signature in database
GPG Key ID: 9CC5B105D03521A2
2 changed files with 23 additions and 2 deletions

@ -300,7 +300,7 @@ func (s *commitmentChain) tail() *commitment {
// * .SignNextCommitment()
// * Called one one wishes to sign the next commitment, either initiating a
// new state update, or responding to a received commitment.
/// * .ReceiveNewCommitment()
// * .ReceiveNewCommitment()
// * Called upon receipt of a new commitment from the remote party. If the
// new commitment is valid, then a revocation should immediately be
// generated and sent.
@ -497,6 +497,9 @@ func NewLightningChannel(signer Signer, bio BlockChainIO,
return
}
// TODO(roasbeef): only close channel if we detect that it's
// not our transaction?
// If the channel's doesn't already indicate that a commitment
// transaction has been broadcast on-chain, then this means the
// remote party broadcasted their commitment transaction.
@ -675,6 +678,15 @@ func (lc *LightningChannel) fetchCommitmentView(remoteChain bool,
}
}
// Set the state hint of the commitment transaction to facilitate
// quickly recovering the necessary penalty state in the case of an
// uncooperative broadcast.
obsfucator := lc.channelState.StateHintObsfucator
stateNum := uint32(nextHeight)
if err := SetStateNumHint(commitTx, stateNum, obsfucator); err != nil {
return nil, err
}
// Sort the transactions according to the agreed upon cannonical
// ordering. This lets us skip sending the entire transaction over,
// instead we'll just send signatures.

@ -167,7 +167,7 @@ func forceStateTransition(chanA, chanB *LightningChannel) error {
}
// createTestChannels creates two test channels funded with 10 BTC, with 5 BTC
// allocated to each side.
// allocated to each side. Within the channel, Alice is the initiator.
func createTestChannels(revocationWindow int) (*LightningChannel, *LightningChannel, func(), error) {
aliceKeyPriv, aliceKeyPub := btcec.PrivKeyFromBytes(btcec.S256(),
testWalletPrivKey)
@ -228,9 +228,15 @@ func createTestChannels(revocationWindow int) (*LightningChannel, *LightningChan
return nil, nil, nil, err
}
var obsfucator [StateHintSize]byte
copy(obsfucator[:], aliceFirstRevoke[:])
aliceChannelState := &channeldb.OpenChannel{
IdentityPub: aliceKeyPub,
ChanID: prevOut,
ChanType: channeldb.SingleFunder,
IsInitiator: true,
StateHintObsfucator: obsfucator,
OurCommitKey: aliceKeyPub,
TheirCommitKey: bobKeyPub,
Capacity: channelCapacity,
@ -251,6 +257,9 @@ func createTestChannels(revocationWindow int) (*LightningChannel, *LightningChan
bobChannelState := &channeldb.OpenChannel{
IdentityPub: bobKeyPub,
ChanID: prevOut,
ChanType: channeldb.SingleFunder,
IsInitiator: false,
StateHintObsfucator: obsfucator,
OurCommitKey: bobKeyPub,
TheirCommitKey: aliceKeyPub,
Capacity: channelCapacity,