Skip to content

Commit 034cba5

Browse files
committed
loopdb/loopout: add field SwapPublicationDeadline to LoopOutContract
We also add a migration for the new LoopOut DB format.
1 parent a6bb2e5 commit 034cba5

File tree

6 files changed

+94
-12
lines changed

6 files changed

+94
-12
lines changed

loopdb/loopout.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,12 @@ type LoopOutContract struct {
4545
// MaxPrepayRoutingFee is the maximum off-chain fee in msat that may be
4646
// paid for the prepayment to the server.
4747
MaxPrepayRoutingFee btcutil.Amount
48+
49+
// SwapPublicationDeadline is a timestamp that the server commits to
50+
// have the on-chain swap published by. It is set by the client to
51+
// allow the server to delay the publication in exchange for possibly
52+
// lower fees.
53+
SwapPublicationDeadline time.Time
4854
}
4955

5056
// LoopOut is a combination of the contract and the updates.
@@ -158,6 +164,13 @@ func deserializeLoopOutContract(value []byte, chainParams *chaincfg.Params) (
158164
contract.UnchargeChannel = &unchargeChannel
159165
}
160166

167+
var deadlineNano int64
168+
err = binary.Read(r, byteOrder, &deadlineNano)
169+
if err != nil {
170+
return nil, err
171+
}
172+
contract.SwapPublicationDeadline = time.Unix(0, deadlineNano)
173+
161174
return &contract, nil
162175
}
163176

@@ -243,5 +256,10 @@ func serializeLoopOutContract(swap *LoopOutContract) (
243256
return nil, err
244257
}
245258

259+
err = binary.Write(&b, byteOrder, swap.SwapPublicationDeadline.UnixNano())
260+
if err != nil {
261+
return nil, err
262+
}
263+
246264
return b.Bytes(), nil
247265
}

loopdb/meta.go

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"errors"
55
"fmt"
66

7+
"github.com/btcsuite/btcd/chaincfg"
78
"github.com/coreos/bbolt"
89
)
910

@@ -24,14 +25,17 @@ var (
2425
// migration is a function which takes a prior outdated version of the database
2526
// instances and mutates the key/bucket structure to arrive at a more
2627
// up-to-date version of the database.
27-
type migration func(tx *bbolt.Tx) error
28+
type migration func(tx *bbolt.Tx, chainParams *chaincfg.Params) error
2829

2930
var (
3031
// dbVersions is storing all versions of database. If current version
3132
// of database don't match with latest version this list will be used
3233
// for retrieving all migration function that are need to apply to the
3334
// current db.
34-
migrations = []migration{migrateCosts}
35+
migrations = []migration{
36+
migrateCosts,
37+
migrateSwapPublicationDeadline,
38+
}
3539

3640
latestDBVersion = uint32(len(migrations))
3741
)
@@ -76,7 +80,7 @@ func setDBVersion(tx *bbolt.Tx, version uint32) error {
7680
// syncVersions function is used for safe db version synchronization. It
7781
// applies migration functions to the current database and recovers the
7882
// previous state of db if at least one error/panic appeared during migration.
79-
func syncVersions(db *bbolt.DB) error {
83+
func syncVersions(db *bbolt.DB, chainParams *chaincfg.Params) error {
8084
currentVersion, err := getDBVersion(db)
8185
if err != nil {
8286
return err
@@ -112,7 +116,7 @@ func syncVersions(db *bbolt.DB) error {
112116
log.Infof("Applying migration #%v", v+1)
113117

114118
migration := migrations[v]
115-
if err := migration(tx); err != nil {
119+
if err := migration(tx, chainParams); err != nil {
116120
log.Infof("Unable to apply migration #%v",
117121
v+1)
118122
return err

loopdb/migration_01_costs.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,13 @@ import (
44
"errors"
55
"fmt"
66

7+
"github.com/btcsuite/btcd/chaincfg"
78
"github.com/coreos/bbolt"
89
)
910

1011
// noMigrationAvailable is the fall back migration in case there is no migration
1112
// implemented.
12-
func migrateCosts(tx *bbolt.Tx) error {
13+
func migrateCosts(tx *bbolt.Tx, _ *chaincfg.Params) error {
1314
if err := migrateCostsForBucket(tx, loopInBucketKey); err != nil {
1415
return err
1516
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package loopdb
2+
3+
import (
4+
"bytes"
5+
"errors"
6+
"fmt"
7+
8+
"github.com/btcsuite/btcd/chaincfg"
9+
"github.com/coreos/bbolt"
10+
)
11+
12+
// migrateSwapPublicationDeadline migrates the database to v02, by adding the
13+
// SwapPublicationDeadline field to loop out contracts.
14+
func migrateSwapPublicationDeadline(tx *bbolt.Tx, chainParams *chaincfg.Params) error {
15+
rootBucket := tx.Bucket(loopOutBucketKey)
16+
if rootBucket == nil {
17+
return errors.New("bucket does not exist")
18+
}
19+
20+
return rootBucket.ForEach(func(swapHash, v []byte) error {
21+
// Only go into things that we know are sub-bucket
22+
// keys.
23+
if v != nil {
24+
return nil
25+
}
26+
27+
// From the root bucket, we'll grab the next swap
28+
// bucket for this swap from its swaphash.
29+
swapBucket := rootBucket.Bucket(swapHash)
30+
if swapBucket == nil {
31+
return fmt.Errorf("swap bucket %x not found",
32+
swapHash)
33+
}
34+
35+
// With the main swap bucket obtained, we'll grab the
36+
// raw swap contract bytes.
37+
contractBytes := swapBucket.Get(contractKey)
38+
if contractBytes == nil {
39+
return errors.New("contract not found")
40+
}
41+
42+
// Write the current contract serialization into a buffer.
43+
b := &bytes.Buffer{}
44+
if _, err := b.Write(contractBytes); err != nil {
45+
return err
46+
}
47+
48+
// We migrate to the new format by copying the first 8 bytes
49+
// (the creation time) to the end (the swap deadline)
50+
var swapDeadline [8]byte
51+
copy(swapDeadline[:], contractBytes[:8])
52+
if _, err := b.Write(swapDeadline[:]); err != nil {
53+
return err
54+
}
55+
56+
return swapBucket.Put(contractKey, b.Bytes())
57+
})
58+
}

loopdb/store.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ func NewBoltSwapStore(dbPath string, chainParams *chaincfg.Params) (
135135

136136
// Finally, before we start, we'll sync the DB versions to pick up any
137137
// possible DB migrations.
138-
err = syncVersions(bdb)
138+
err = syncVersions(bdb, chainParams)
139139
if err != nil {
140140
return nil, err
141141
}

loopdb/store_test.go

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -82,12 +82,13 @@ func TestLoopOutStore(t *testing.T) {
8282
// doesn't interfere with DeepEqual.
8383
InitiationTime: time.Unix(0, initiationTime.UnixNano()),
8484
},
85-
MaxPrepayRoutingFee: 40,
86-
PrepayInvoice: "prepayinvoice",
87-
DestAddr: destAddr,
88-
SwapInvoice: "swapinvoice",
89-
MaxSwapRoutingFee: 30,
90-
SweepConfTarget: 2,
85+
MaxPrepayRoutingFee: 40,
86+
PrepayInvoice: "prepayinvoice",
87+
DestAddr: destAddr,
88+
SwapInvoice: "swapinvoice",
89+
MaxSwapRoutingFee: 30,
90+
SweepConfTarget: 2,
91+
SwapPublicationDeadline: time.Unix(0, initiationTime.UnixNano()),
9192
}
9293

9394
// checkSwap is a test helper function that'll assert the state of a

0 commit comments

Comments
 (0)