watchtower/wtdb: create embedded ClientSessionBody

This commit splits out the portions of the ClientSession into an
embedded ClientSessionBody, since these fields will be serialized
together on-disk.
This commit is contained in:
Conner Fromknecht 2019-05-23 20:47:49 -07:00
parent 5ad9530502
commit 1db9bf2fd4
No known key found for this signature in database
GPG Key ID: E7D737B67FA592C7
6 changed files with 59 additions and 37 deletions

@ -126,8 +126,7 @@ func (t *backupTask) inputs() map[wire.OutPoint]input.Input {
// SessionInfo's policy. If no error is returned, the task has been bound to the
// session and can be queued to upload to the tower. Otherwise, the bind failed
// and should be rescheduled with a different session.
func (t *backupTask) bindSession(session *wtdb.ClientSession) error {
func (t *backupTask) bindSession(session *wtdb.ClientSessionBody) error {
// First we'll begin by deriving a weight estimate for the justice
// transaction. The final weight can be different depending on whether
// the watchtower is taking a reward.

@ -69,7 +69,7 @@ type backupTaskTest struct {
expSweepAmt int64
expRewardAmt int64
expRewardScript []byte
session *wtdb.ClientSession
session *wtdb.ClientSessionBody
bindErr error
expSweepScript []byte
signer input.Signer
@ -205,7 +205,7 @@ func genTaskTest(
expSweepAmt: expSweepAmt,
expRewardAmt: expRewardAmt,
expRewardScript: rewardScript,
session: &wtdb.ClientSession{
session: &wtdb.ClientSessionBody{
Policy: wtpolicy.Policy{
BlobType: blobType,
SweepFeeRate: sweepFeeRate,

@ -417,14 +417,15 @@ func (n *sessionNegotiator) tryAddress(privKey *btcec.PrivateKey,
privKey.PubKey(),
)
clientSession := &wtdb.ClientSession{
TowerID: tower.ID,
ClientSessionBody: wtdb.ClientSessionBody{
TowerID: tower.ID,
KeyIndex: keyIndex,
Policy: n.cfg.Policy,
RewardPkScript: rewardPkScript,
},
Tower: tower,
KeyIndex: keyIndex,
SessionPrivKey: privKey,
ID: sessionID,
Policy: n.cfg.Policy,
SeqNum: 0,
RewardPkScript: rewardPkScript,
}
err = n.cfg.DB.CreateClientSession(clientSession)

@ -215,7 +215,7 @@ func (q *sessionQueue) AcceptTask(task *backupTask) (reserveStatus, bool) {
//
// TODO(conner): queue backups and retry with different session params.
case reserveAvailable:
err := task.bindSession(q.cfg.ClientSession)
err := task.bindSession(&q.cfg.ClientSession.ClientSessionBody)
if err != nil {
q.queueCond.L.Unlock()
log.Debugf("SessionQueue %s rejected backup chanid=%s "+

@ -46,8 +46,48 @@ var (
type ClientSession struct {
// ID is the client's public key used when authenticating with the
// tower.
//
// NOTE: This value is not serialized with the body of the struct, it
// should be set and recovered as the ClientSession's key.
ID SessionID
ClientSessionBody
// CommittedUpdates is a sorted list of unacked updates. These updates
// can be resent after a restart if the updates failed to send or
// receive an acknowledgment.
//
// NOTE: This list is serialized in it's own bucket, separate from the
// body of the ClientSession. The representation on disk is a key value
// map from sequence number to CommittedUpdateBody to allow efficient
// insertion and retrieval.
CommittedUpdates []CommittedUpdate
// AckedUpdates is a map from sequence number to backup id to record
// which revoked states were uploaded via this session.
//
// NOTE: This map is serialized in it's own bucket, separate from the
// body of the ClientSession.
AckedUpdates map[uint16]BackupID
// Tower holds the pubkey and address of the watchtower.
//
// NOTE: This value is not serialized. It is recovered by looking up the
// tower with TowerID.
Tower *Tower
// SessionPrivKey is the ephemeral secret key used to connect to the
// watchtower.
//
// NOTE: This value is not serialized. It is derived using the KeyIndex
// on startup to avoid storing private keys on disk.
SessionPrivKey *btcec.PrivateKey
}
// ClientSessionBody represents the primary components of a ClientSession that
// are serialized together within the database. The CommittedUpdates and
// AckedUpdates are serialized in buckets separate from the body.
type ClientSessionBody struct {
// SeqNum is the next unallocated sequence number that can be sent to
// the tower.
SeqNum uint16
@ -59,25 +99,12 @@ type ClientSession struct {
// Tower with which the session is negotiated.
TowerID TowerID
// Tower holds the pubkey and address of the watchtower.
//
// NOTE: This value is not serialized. It is recovered by looking up the
// tower with TowerID.
Tower *Tower
// KeyIndex is the index of key locator used to derive the client's
// session key so that it can authenticate with the tower to update its
// session. In order to rederive the private key, the key locator should
// use the keychain.KeyFamilyTowerSession key family.
KeyIndex uint32
// SessionPrivKey is the ephemeral secret key used to connect to the
// watchtower.
//
// NOTE: This value is not serialized. It is derived using the KeyIndex
// on startup to avoid storing private keys on disk.
SessionPrivKey *btcec.PrivateKey
// Policy holds the negotiated session parameters.
Policy wtpolicy.Policy
@ -86,14 +113,7 @@ type ClientSession struct {
// specifies a reward output.
RewardPkScript []byte
// CommittedUpdates is a sorted list of unacked updates. These updates
// can be resent after a restart if the updates failed to send or
// receive an acknowledgment.
CommittedUpdates []CommittedUpdate
// AckedUpdates is a map from sequence number to backup id to record
// which revoked states were uploaded via this session.
AckedUpdates map[uint16]BackupID
}
// BackupID identifies a particular revoked, remote commitment by channel id and

@ -122,13 +122,15 @@ func (m *ClientDB) CreateClientSession(session *wtdb.ClientSession) error {
delete(m.indexes, session.TowerID)
m.activeSessions[session.ID] = &wtdb.ClientSession{
TowerID: session.TowerID,
KeyIndex: session.KeyIndex,
ID: session.ID,
Policy: session.Policy,
SeqNum: session.SeqNum,
TowerLastApplied: session.TowerLastApplied,
RewardPkScript: cloneBytes(session.RewardPkScript),
ID: session.ID,
ClientSessionBody: wtdb.ClientSessionBody{
SeqNum: session.SeqNum,
TowerLastApplied: session.TowerLastApplied,
TowerID: session.TowerID,
KeyIndex: session.KeyIndex,
Policy: session.Policy,
RewardPkScript: cloneBytes(session.RewardPkScript),
},
CommittedUpdates: make([]wtdb.CommittedUpdate, 0),
AckedUpdates: make(map[uint16]wtdb.BackupID),
}