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:
6 files changed
+59
-37
No files matched your search
@@ -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
|
// 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
|
// session and can be queued to upload to the tower. Otherwise, the bind failed
|
||||||
// and should be rescheduled with a different session.
|
// 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
|
// First we'll begin by deriving a weight estimate for the justice
|
||||||
// transaction. The final weight can be different depending on whether
|
// transaction. The final weight can be different depending on whether
|
||||||
// the watchtower is taking a reward.
|
// the watchtower is taking a reward.
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ type backupTaskTest struct {
|
|||||||
expSweepAmt int64
|
expSweepAmt int64
|
||||||
expRewardAmt int64
|
expRewardAmt int64
|
||||||
expRewardScript []byte
|
expRewardScript []byte
|
||||||
session *wtdb.ClientSession
|
session *wtdb.ClientSessionBody
|
||||||
bindErr error
|
bindErr error
|
||||||
expSweepScript []byte
|
expSweepScript []byte
|
||||||
signer input.Signer
|
signer input.Signer
|
||||||
@@ -205,7 +205,7 @@ func genTaskTest(
|
|||||||
expSweepAmt: expSweepAmt,
|
expSweepAmt: expSweepAmt,
|
||||||
expRewardAmt: expRewardAmt,
|
expRewardAmt: expRewardAmt,
|
||||||
expRewardScript: rewardScript,
|
expRewardScript: rewardScript,
|
||||||
session: &wtdb.ClientSession{
|
session: &wtdb.ClientSessionBody{
|
||||||
Policy: wtpolicy.Policy{
|
Policy: wtpolicy.Policy{
|
||||||
BlobType: blobType,
|
BlobType: blobType,
|
||||||
SweepFeeRate: sweepFeeRate,
|
SweepFeeRate: sweepFeeRate,
|
||||||
|
|||||||
@@ -417,14 +417,15 @@ func (n *sessionNegotiator) tryAddress(privKey *btcec.PrivateKey,
|
|||||||
privKey.PubKey(),
|
privKey.PubKey(),
|
||||||
)
|
)
|
||||||
clientSession := &wtdb.ClientSession{
|
clientSession := &wtdb.ClientSession{
|
||||||
TowerID: tower.ID,
|
ClientSessionBody: wtdb.ClientSessionBody{
|
||||||
|
TowerID: tower.ID,
|
||||||
|
KeyIndex: keyIndex,
|
||||||
|
Policy: n.cfg.Policy,
|
||||||
|
RewardPkScript: rewardPkScript,
|
||||||
|
},
|
||||||
Tower: tower,
|
Tower: tower,
|
||||||
KeyIndex: keyIndex,
|
|
||||||
SessionPrivKey: privKey,
|
SessionPrivKey: privKey,
|
||||||
ID: sessionID,
|
ID: sessionID,
|
||||||
Policy: n.cfg.Policy,
|
|
||||||
SeqNum: 0,
|
|
||||||
RewardPkScript: rewardPkScript,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
err = n.cfg.DB.CreateClientSession(clientSession)
|
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.
|
// TODO(conner): queue backups and retry with different session params.
|
||||||
case reserveAvailable:
|
case reserveAvailable:
|
||||||
err := task.bindSession(q.cfg.ClientSession)
|
err := task.bindSession(&q.cfg.ClientSession.ClientSessionBody)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
q.queueCond.L.Unlock()
|
q.queueCond.L.Unlock()
|
||||||
log.Debugf("SessionQueue %s rejected backup chanid=%s "+
|
log.Debugf("SessionQueue %s rejected backup chanid=%s "+
|
||||||
|
|||||||
@@ -46,8 +46,48 @@ var (
|
|||||||
type ClientSession struct {
|
type ClientSession struct {
|
||||||
// ID is the client's public key used when authenticating with the
|
// ID is the client's public key used when authenticating with the
|
||||||
// tower.
|
// 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
|
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
|
// SeqNum is the next unallocated sequence number that can be sent to
|
||||||
// the tower.
|
// the tower.
|
||||||
SeqNum uint16
|
SeqNum uint16
|
||||||
@@ -59,25 +99,12 @@ type ClientSession struct {
|
|||||||
// Tower with which the session is negotiated.
|
// Tower with which the session is negotiated.
|
||||||
TowerID TowerID
|
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
|
// 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 key so that it can authenticate with the tower to update its
|
||||||
// session. In order to rederive the private key, the key locator should
|
// session. In order to rederive the private key, the key locator should
|
||||||
// use the keychain.KeyFamilyTowerSession key family.
|
// use the keychain.KeyFamilyTowerSession key family.
|
||||||
KeyIndex uint32
|
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 holds the negotiated session parameters.
|
||||||
Policy wtpolicy.Policy
|
Policy wtpolicy.Policy
|
||||||
|
|
||||||
@@ -86,14 +113,7 @@ type ClientSession struct {
|
|||||||
// specifies a reward output.
|
// specifies a reward output.
|
||||||
RewardPkScript []byte
|
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
|
// 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)
|
delete(m.indexes, session.TowerID)
|
||||||
|
|
||||||
m.activeSessions[session.ID] = &wtdb.ClientSession{
|
m.activeSessions[session.ID] = &wtdb.ClientSession{
|
||||||
TowerID: session.TowerID,
|
ID: session.ID,
|
||||||
KeyIndex: session.KeyIndex,
|
ClientSessionBody: wtdb.ClientSessionBody{
|
||||||
ID: session.ID,
|
SeqNum: session.SeqNum,
|
||||||
Policy: session.Policy,
|
TowerLastApplied: session.TowerLastApplied,
|
||||||
SeqNum: session.SeqNum,
|
TowerID: session.TowerID,
|
||||||
TowerLastApplied: session.TowerLastApplied,
|
KeyIndex: session.KeyIndex,
|
||||||
RewardPkScript: cloneBytes(session.RewardPkScript),
|
Policy: session.Policy,
|
||||||
|
RewardPkScript: cloneBytes(session.RewardPkScript),
|
||||||
|
},
|
||||||
CommittedUpdates: make([]wtdb.CommittedUpdate, 0),
|
CommittedUpdates: make([]wtdb.CommittedUpdate, 0),
|
||||||
AckedUpdates: make(map[uint16]wtdb.BackupID),
|
AckedUpdates: make(map[uint16]wtdb.BackupID),
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user