From 4e6dc3863b7a76bd21241ff22da5744a1aad7528 Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Wed, 31 Oct 2018 20:42:04 -0700 Subject: [PATCH] watchtower/wtdb/session_info: compute rewards outputs --- watchtower/wtdb/session_info.go | 61 +++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/watchtower/wtdb/session_info.go b/watchtower/wtdb/session_info.go index ddb4347d..23775fe6 100644 --- a/watchtower/wtdb/session_info.go +++ b/watchtower/wtdb/session_info.go @@ -3,6 +3,7 @@ package wtdb import ( "errors" + "github.com/btcsuite/btcutil" "github.com/lightningnetwork/lnd/lnwallet" ) @@ -34,6 +35,11 @@ var ( // number larger than the session's max number of updates. ErrSessionConsumed = errors.New("all session updates have been " + "consumed") + + // ErrFeeExceedsInputs signals that the total input value of breaching + // commitment txn is insufficient to cover the fees required to sweep + // it. + ErrFeeExceedsInputs = errors.New("sweep fee exceeds input values") ) // SessionInfo holds the negotiated session parameters for single session id, @@ -103,3 +109,58 @@ func (s *SessionInfo) AcceptUpdateSequence(seqNum, lastApplied uint16) error { return nil } + +// ComputeSweepOutputs splits the total funds in a breaching commitment +// transaction between the victim and the tower, according to the sweep fee rate +// and reward rate. The fees are first subtracted from the overall total, before +// splitting the remaining balance amongst the victim and tower. +func (s *SessionInfo) ComputeSweepOutputs(totalAmt btcutil.Amount, + txVSize int64) (btcutil.Amount, btcutil.Amount, error) { + + txFee := s.SweepFeeRate.FeeForWeight(txVSize) + if txFee > totalAmt { + return 0, 0, ErrFeeExceedsInputs + } + + totalAmt -= txFee + + // Apply the reward rate to the remaining total, specified in millionths + // of the available balance. + rewardAmt := (totalAmt*btcutil.Amount(s.RewardRate) + 999999) / 1000000 + sweepAmt := totalAmt - rewardAmt + + // TODO(conner): check dustiness + + return sweepAmt, rewardAmt, nil +} + +// Match is returned in response to a database query for a breach hints +// contained in a particular block. The match encapsulates all data required to +// properly decrypt a client's encrypted blob, and pursue action on behalf of +// the victim by reconstructing the justice transaction and broadcasting it to +// the network. +// +// NOTE: It is possible for a match to cause a false positive, since they are +// matched on a prefix of the txid. In such an event, the likely behavior is +// that the payload will fail to decrypt. +type Match struct { + // ID is the session id of the client who uploaded the state update. + ID SessionID + + // SeqNum is the session sequence number occupied by the client's state + // update. Together with ID, this allows the tower to derive the + // appropriate nonce for decryption. + SeqNum uint16 + + // Hint is the breach hint that triggered the match. + Hint BreachHint + + // EncryptedBlob is the encrypted payload containing the justice kit + // uploaded by the client. + EncryptedBlob []byte + + // SessionInfo is the contract negotiated between tower and client, that + // provides input parameters such as fee rate, reward rate, and reward + // address when attempting to reconstruct the justice transaction. + SessionInfo *SessionInfo +}