lnwallet: pack update logs into Dual

This commit, like the last one packs the update logs into a symmetric
Dual structure. This will allow us to index into them more concisely
in higher order logic.
This commit is contained in:
Keagan McClelland committed 2024-08-28 13:58:33 -07:00
1 parent 8077862225
commit 2e7fbc446f
2 files changed
+235 -193

No files matched your search

+130 -103
View File
@@ -335,21 +335,23 @@ func testAddSettleWorkflow(t *testing.T, tweakless bool,
// The logs of both sides should now be cleared since the entry adding
// the HTLC should have been removed once both sides receive the
// revocation.
if aliceChannel.localUpdateLog.Len() != 0 {
if aliceChannel.updateLogs.Local.Len() != 0 {
t.Fatalf("alice's local not updated, should be empty, has %v "+
"entries instead", aliceChannel.localUpdateLog.Len())
"entries instead", aliceChannel.updateLogs.Local.Len())
}
if aliceChannel.remoteUpdateLog.Len() != 0 {
if aliceChannel.updateLogs.Remote.Len() != 0 {
t.Fatalf("alice's remote not updated, should be empty, has %v "+
"entries instead", aliceChannel.remoteUpdateLog.Len())
"entries instead", aliceChannel.updateLogs.Remote.Len())
}
if len(aliceChannel.localUpdateLog.updateIndex) != 0 {
t.Fatalf("alice's local log index not cleared, should be empty but "+
"has %v entries", len(aliceChannel.localUpdateLog.updateIndex))
if len(aliceChannel.updateLogs.Local.updateIndex) != 0 {
t.Fatalf("alice's local log index not cleared, should be "+
"empty but has %v entries",
len(aliceChannel.updateLogs.Local.updateIndex))
}
if len(aliceChannel.remoteUpdateLog.updateIndex) != 0 {
t.Fatalf("alice's remote log index not cleared, should be empty but "+
"has %v entries", len(aliceChannel.remoteUpdateLog.updateIndex))
if len(aliceChannel.updateLogs.Remote.updateIndex) != 0 {
t.Fatalf("alice's remote log index not cleared, should be "+
"empty but has %v entries",
len(aliceChannel.updateLogs.Remote.updateIndex))
}
}
@@ -1773,26 +1775,26 @@ func TestStateUpdatePersistence(t *testing.T) {
// Helper method that asserts the expected number of updates are found
// in the update logs.
assertNumLogUpdates := func(numAliceUpdates, numBobUpdates int) {
if aliceChannel.localUpdateLog.Len() != numAliceUpdates {
if aliceChannel.updateLogs.Local.Len() != numAliceUpdates {
t.Fatalf("expected %d local updates, found %d",
numAliceUpdates,
aliceChannel.localUpdateLog.Len())
aliceChannel.updateLogs.Local.Len())
}
if aliceChannel.remoteUpdateLog.Len() != numBobUpdates {
if aliceChannel.updateLogs.Remote.Len() != numBobUpdates {
t.Fatalf("expected %d remote updates, found %d",
numBobUpdates,
aliceChannel.remoteUpdateLog.Len())
aliceChannel.updateLogs.Remote.Len())
}
if bobChannel.localUpdateLog.Len() != numBobUpdates {
if bobChannel.updateLogs.Local.Len() != numBobUpdates {
t.Fatalf("expected %d local updates, found %d",
numBobUpdates,
bobChannel.localUpdateLog.Len())
bobChannel.updateLogs.Local.Len())
}
if bobChannel.remoteUpdateLog.Len() != numAliceUpdates {
if bobChannel.updateLogs.Remote.Len() != numAliceUpdates {
t.Fatalf("expected %d remote updates, found %d",
numAliceUpdates,
bobChannel.remoteUpdateLog.Len())
bobChannel.updateLogs.Remote.Len())
}
}
@@ -1868,62 +1870,72 @@ func TestStateUpdatePersistence(t *testing.T) {
// The state update logs of the new channels and the old channels
// should now be identical other than the height the HTLCs were added.
if aliceChannel.localUpdateLog.logIndex !=
aliceChannelNew.localUpdateLog.logIndex {
if aliceChannel.updateLogs.Local.logIndex !=
aliceChannelNew.updateLogs.Local.logIndex {
t.Fatalf("alice log counter: expected %v, got %v",
aliceChannel.localUpdateLog.logIndex,
aliceChannelNew.localUpdateLog.logIndex)
aliceChannel.updateLogs.Local.logIndex,
aliceChannelNew.updateLogs.Local.logIndex)
}
if aliceChannel.remoteUpdateLog.logIndex !=
aliceChannelNew.remoteUpdateLog.logIndex {
if aliceChannel.updateLogs.Remote.logIndex !=
aliceChannelNew.updateLogs.Remote.logIndex {
t.Fatalf("alice log counter: expected %v, got %v",
aliceChannel.remoteUpdateLog.logIndex,
aliceChannelNew.remoteUpdateLog.logIndex)
aliceChannel.updateLogs.Remote.logIndex,
aliceChannelNew.updateLogs.Remote.logIndex)
}
if aliceChannel.localUpdateLog.Len() !=
aliceChannelNew.localUpdateLog.Len() {
if aliceChannel.updateLogs.Local.Len() !=
aliceChannelNew.updateLogs.Local.Len() {
t.Fatalf("alice log len: expected %v, got %v",
aliceChannel.localUpdateLog.Len(),
aliceChannelNew.localUpdateLog.Len())
aliceChannel.updateLogs.Local.Len(),
aliceChannelNew.updateLogs.Local.Len())
}
if aliceChannel.remoteUpdateLog.Len() !=
aliceChannelNew.remoteUpdateLog.Len() {
if aliceChannel.updateLogs.Remote.Len() !=
aliceChannelNew.updateLogs.Remote.Len() {
t.Fatalf("alice log len: expected %v, got %v",
aliceChannel.remoteUpdateLog.Len(),
aliceChannelNew.remoteUpdateLog.Len())
aliceChannel.updateLogs.Remote.Len(),
aliceChannelNew.updateLogs.Remote.Len())
}
if bobChannel.localUpdateLog.logIndex !=
bobChannelNew.localUpdateLog.logIndex {
if bobChannel.updateLogs.Local.logIndex !=
bobChannelNew.updateLogs.Local.logIndex {
t.Fatalf("bob log counter: expected %v, got %v",
bobChannel.localUpdateLog.logIndex,
bobChannelNew.localUpdateLog.logIndex)
bobChannel.updateLogs.Local.logIndex,
bobChannelNew.updateLogs.Local.logIndex)
}
if bobChannel.remoteUpdateLog.logIndex !=
bobChannelNew.remoteUpdateLog.logIndex {
if bobChannel.updateLogs.Remote.logIndex !=
bobChannelNew.updateLogs.Remote.logIndex {
t.Fatalf("bob log counter: expected %v, got %v",
bobChannel.remoteUpdateLog.logIndex,
bobChannelNew.remoteUpdateLog.logIndex)
bobChannel.updateLogs.Remote.logIndex,
bobChannelNew.updateLogs.Remote.logIndex)
}
if bobChannel.localUpdateLog.Len() !=
bobChannelNew.localUpdateLog.Len() {
if bobChannel.updateLogs.Local.Len() !=
bobChannelNew.updateLogs.Local.Len() {
t.Fatalf("bob log len: expected %v, got %v",
bobChannel.localUpdateLog.Len(),
bobChannelNew.localUpdateLog.Len())
bobChannel.updateLogs.Local.Len(),
bobChannelNew.updateLogs.Local.Len())
}
if bobChannel.remoteUpdateLog.Len() !=
bobChannelNew.remoteUpdateLog.Len() {
if bobChannel.updateLogs.Remote.Len() !=
bobChannelNew.updateLogs.Remote.Len() {
t.Fatalf("bob log len: expected %v, got %v",
bobChannel.remoteUpdateLog.Len(),
bobChannelNew.remoteUpdateLog.Len())
bobChannel.updateLogs.Remote.Len(),
bobChannelNew.updateLogs.Remote.Len())
}
// TODO(roasbeef): expand test to also ensure state revocation log has
// proper pk scripts
// Newly generated pkScripts for HTLCs should be the same as in the old channel.
for _, entry := range aliceChannel.localUpdateLog.htlcIndex {
for _, entry := range aliceChannel.updateLogs.Local.htlcIndex {
htlc := entry.Value
restoredHtlc := aliceChannelNew.localUpdateLog.lookupHtlc(htlc.HtlcIndex)
restoredHtlc := aliceChannelNew.updateLogs.Local.lookupHtlc(
htlc.HtlcIndex,
)
if !bytes.Equal(htlc.ourPkScript, restoredHtlc.ourPkScript) {
t.Fatalf("alice ourPkScript in ourLog: expected %X, got %X",
htlc.ourPkScript[:5], restoredHtlc.ourPkScript[:5])
@@ -1933,9 +1945,11 @@ func TestStateUpdatePersistence(t *testing.T) {
htlc.theirPkScript[:5], restoredHtlc.theirPkScript[:5])
}
}
for _, entry := range aliceChannel.remoteUpdateLog.htlcIndex {
for _, entry := range aliceChannel.updateLogs.Remote.htlcIndex {
htlc := entry.Value
restoredHtlc := aliceChannelNew.remoteUpdateLog.lookupHtlc(htlc.HtlcIndex)
restoredHtlc := aliceChannelNew.updateLogs.Remote.lookupHtlc(
htlc.HtlcIndex,
)
if !bytes.Equal(htlc.ourPkScript, restoredHtlc.ourPkScript) {
t.Fatalf("alice ourPkScript in theirLog: expected %X, got %X",
htlc.ourPkScript[:5], restoredHtlc.ourPkScript[:5])
@@ -1945,9 +1959,11 @@ func TestStateUpdatePersistence(t *testing.T) {
htlc.theirPkScript[:5], restoredHtlc.theirPkScript[:5])
}
}
for _, entry := range bobChannel.localUpdateLog.htlcIndex {
for _, entry := range bobChannel.updateLogs.Local.htlcIndex {
htlc := entry.Value
restoredHtlc := bobChannelNew.localUpdateLog.lookupHtlc(htlc.HtlcIndex)
restoredHtlc := bobChannelNew.updateLogs.Local.lookupHtlc(
htlc.HtlcIndex,
)
if !bytes.Equal(htlc.ourPkScript, restoredHtlc.ourPkScript) {
t.Fatalf("bob ourPkScript in ourLog: expected %X, got %X",
htlc.ourPkScript[:5], restoredHtlc.ourPkScript[:5])
@@ -1957,9 +1973,11 @@ func TestStateUpdatePersistence(t *testing.T) {
htlc.theirPkScript[:5], restoredHtlc.theirPkScript[:5])
}
}
for _, entry := range bobChannel.remoteUpdateLog.htlcIndex {
for _, entry := range bobChannel.updateLogs.Remote.htlcIndex {
htlc := entry.Value
restoredHtlc := bobChannelNew.remoteUpdateLog.lookupHtlc(htlc.HtlcIndex)
restoredHtlc := bobChannelNew.updateLogs.Remote.lookupHtlc(
htlc.HtlcIndex,
)
if !bytes.Equal(htlc.ourPkScript, restoredHtlc.ourPkScript) {
t.Fatalf("bob ourPkScript in theirLog: expected %X, got %X",
htlc.ourPkScript[:5], restoredHtlc.ourPkScript[:5])
@@ -3245,39 +3263,39 @@ func TestChanSyncOweCommitment(t *testing.T) {
// Alice's local log counter should be 4 and her HTLC index 3. She
// should detect Bob's remote log counter as being 3 and his HTLC index
// 3 as well.
if aliceChannel.localUpdateLog.logIndex != 4 {
if aliceChannel.updateLogs.Local.logIndex != 4 {
t.Fatalf("incorrect log index: expected %v, got %v", 4,
aliceChannel.localUpdateLog.logIndex)
aliceChannel.updateLogs.Local.logIndex)
}
if aliceChannel.localUpdateLog.htlcCounter != 1 {
if aliceChannel.updateLogs.Local.htlcCounter != 1 {
t.Fatalf("incorrect htlc index: expected %v, got %v", 1,
aliceChannel.localUpdateLog.htlcCounter)
aliceChannel.updateLogs.Local.htlcCounter)
}
if aliceChannel.remoteUpdateLog.logIndex != 3 {
if aliceChannel.updateLogs.Remote.logIndex != 3 {
t.Fatalf("incorrect log index: expected %v, got %v", 3,
aliceChannel.localUpdateLog.logIndex)
aliceChannel.updateLogs.Local.logIndex)
}
if aliceChannel.remoteUpdateLog.htlcCounter != 3 {
if aliceChannel.updateLogs.Remote.htlcCounter != 3 {
t.Fatalf("incorrect htlc index: expected %v, got %v", 3,
aliceChannel.localUpdateLog.htlcCounter)
aliceChannel.updateLogs.Local.htlcCounter)
}
// Bob should also have the same state, but mirrored.
if bobChannel.localUpdateLog.logIndex != 3 {
if bobChannel.updateLogs.Local.logIndex != 3 {
t.Fatalf("incorrect log index: expected %v, got %v", 3,
bobChannel.localUpdateLog.logIndex)
bobChannel.updateLogs.Local.logIndex)
}
if bobChannel.localUpdateLog.htlcCounter != 3 {
if bobChannel.updateLogs.Local.htlcCounter != 3 {
t.Fatalf("incorrect htlc index: expected %v, got %v", 3,
bobChannel.localUpdateLog.htlcCounter)
bobChannel.updateLogs.Local.htlcCounter)
}
if bobChannel.remoteUpdateLog.logIndex != 4 {
if bobChannel.updateLogs.Remote.logIndex != 4 {
t.Fatalf("incorrect log index: expected %v, got %v", 4,
bobChannel.localUpdateLog.logIndex)
bobChannel.updateLogs.Local.logIndex)
}
if bobChannel.remoteUpdateLog.htlcCounter != 1 {
if bobChannel.updateLogs.Remote.htlcCounter != 1 {
t.Fatalf("incorrect htlc index: expected %v, got %v", 1,
bobChannel.localUpdateLog.htlcCounter)
bobChannel.updateLogs.Local.htlcCounter)
}
// We'll conclude the test by having Bob settle Alice's HTLC, then
@@ -4507,7 +4525,7 @@ func TestFeeUpdateOldDiskFormat(t *testing.T) {
t.Helper()
expUpd := expFee + expAdd
upd, fees := countLog(aliceChannel.localUpdateLog)
upd, fees := countLog(aliceChannel.updateLogs.Local)
if upd != expUpd {
t.Fatalf("expected %d updates, found %d in Alice's "+
"log", expUpd, upd)
@@ -4516,7 +4534,7 @@ func TestFeeUpdateOldDiskFormat(t *testing.T) {
t.Fatalf("expected %d fee updates, found %d in "+
"Alice's log", expFee, fees)
}
upd, fees = countLog(bobChannel.remoteUpdateLog)
upd, fees = countLog(bobChannel.updateLogs.Remote)
if upd != expUpd {
t.Fatalf("expected %d updates, found %d in Bob's log",
expUpd, upd)
@@ -5215,7 +5233,7 @@ func TestChanCommitWeightDustHtlcs(t *testing.T) {
lc.commitChains.Local.tip().theirMessageIndex
htlcView := lc.fetchHTLCView(remoteACKedIndex,
lc.localUpdateLog.logIndex)
lc.updateLogs.Local.logIndex)
_, w := lc.availableCommitmentBalance(
htlcView, lntypes.Remote, FeeBuffer,
@@ -6922,20 +6940,20 @@ func TestChannelRestoreUpdateLogs(t *testing.T) {
// compare all the logs between the old and new channels, to make sure
// they all got restored properly.
err = compareLogs(aliceChannel.localUpdateLog,
newAliceChannel.localUpdateLog)
err = compareLogs(aliceChannel.updateLogs.Local,
newAliceChannel.updateLogs.Local)
require.NoError(t, err, "alice local log not restored")
err = compareLogs(aliceChannel.remoteUpdateLog,
newAliceChannel.remoteUpdateLog)
err = compareLogs(aliceChannel.updateLogs.Remote,
newAliceChannel.updateLogs.Remote)
require.NoError(t, err, "alice remote log not restored")
err = compareLogs(bobChannel.localUpdateLog,
newBobChannel.localUpdateLog)
err = compareLogs(bobChannel.updateLogs.Local,
newBobChannel.updateLogs.Local)
require.NoError(t, err, "bob local log not restored")
err = compareLogs(bobChannel.remoteUpdateLog,
newBobChannel.remoteUpdateLog)
err = compareLogs(bobChannel.updateLogs.Remote,
newBobChannel.updateLogs.Remote)
require.NoError(t, err, "bob remote log not restored")
}
@@ -6968,8 +6986,9 @@ func assertInLog(t *testing.T, log *updateLog, numAdds, numFails int) {
// the local and remote update log of the given channel.
func assertInLogs(t *testing.T, channel *LightningChannel, numAddsLocal,
numFailsLocal, numAddsRemote, numFailsRemote int) {
assertInLog(t, channel.localUpdateLog, numAddsLocal, numFailsLocal)
assertInLog(t, channel.remoteUpdateLog, numAddsRemote, numFailsRemote)
assertInLog(t, channel.updateLogs.Local, numAddsLocal, numFailsLocal)
assertInLog(t, channel.updateLogs.Remote, numAddsRemote, numFailsRemote)
}
// restoreAndAssert creates a new LightningChannel from the given channel's
@@ -6984,8 +7003,10 @@ func restoreAndAssert(t *testing.T, channel *LightningChannel, numAddsLocal,
)
require.NoError(t, err, "unable to create new channel")
assertInLog(t, newChannel.localUpdateLog, numAddsLocal, numFailsLocal)
assertInLog(t, newChannel.remoteUpdateLog, numAddsRemote, numFailsRemote)
assertInLog(t, newChannel.updateLogs.Local, numAddsLocal, numFailsLocal)
assertInLog(
t, newChannel.updateLogs.Remote, numAddsRemote, numFailsRemote,
)
}
// TestChannelRestoreUpdateLogsFailedHTLC runs through a scenario where an
@@ -7249,16 +7270,18 @@ func TestChannelRestoreCommitHeight(t *testing.T) {
var pd *PaymentDescriptor
if remoteLog {
if newChannel.localUpdateLog.lookupHtlc(htlcIndex) != nil {
h := newChannel.updateLogs.Local.lookupHtlc(htlcIndex)
if h != nil {
t.Fatalf("htlc found in wrong log")
}
pd = newChannel.remoteUpdateLog.lookupHtlc(htlcIndex)
pd = newChannel.updateLogs.Remote.lookupHtlc(htlcIndex)
} else {
if newChannel.remoteUpdateLog.lookupHtlc(htlcIndex) != nil {
h := newChannel.updateLogs.Remote.lookupHtlc(htlcIndex)
if h != nil {
t.Fatalf("htlc found in wrong log")
}
pd = newChannel.localUpdateLog.lookupHtlc(htlcIndex)
pd = newChannel.updateLogs.Local.lookupHtlc(htlcIndex)
}
if pd == nil {
t.Fatalf("htlc not found in log")
@@ -8196,16 +8219,18 @@ func TestFetchParent(t *testing.T) {
// Create a lightning channel with newly initialized
// local and remote logs.
lc := LightningChannel{
localUpdateLog: newUpdateLog(0, 0),
remoteUpdateLog: newUpdateLog(0, 0),
updateLogs: lntypes.Dual[*updateLog]{
Local: newUpdateLog(0, 0),
Remote: newUpdateLog(0, 0),
},
}
// Add the local and remote entries to update logs.
for _, entry := range test.localEntries {
lc.localUpdateLog.appendHtlc(entry)
lc.updateLogs.Local.appendHtlc(entry)
}
for _, entry := range test.remoteEntries {
lc.remoteUpdateLog.appendHtlc(entry)
lc.updateLogs.Remote.appendHtlc(entry)
}
parent, err := lc.fetchParent(
@@ -8532,23 +8557,25 @@ func TestEvaluateView(t *testing.T) {
},
// Create update logs for local and remote.
localUpdateLog: newUpdateLog(0, 0),
remoteUpdateLog: newUpdateLog(0, 0),
updateLogs: lntypes.Dual[*updateLog]{
Local: newUpdateLog(0, 0),
Remote: newUpdateLog(0, 0),
},
}
for _, htlc := range test.ourHtlcs {
if htlc.EntryType == Add {
lc.localUpdateLog.appendHtlc(htlc)
lc.updateLogs.Local.appendHtlc(htlc)
} else {
lc.localUpdateLog.appendUpdate(htlc)
lc.updateLogs.Local.appendUpdate(htlc)
}
}
for _, htlc := range test.theirHtlcs {
if htlc.EntryType == Add {
lc.remoteUpdateLog.appendHtlc(htlc)
lc.updateLogs.Remote.appendHtlc(htlc)
} else {
lc.remoteUpdateLog.appendUpdate(htlc)
lc.updateLogs.Remote.appendUpdate(htlc)
}
}