2019-04-16 12:33:30 +03:00
|
|
|
package contractcourt
|
|
|
|
|
|
|
|
import (
|
2020-11-19 00:45:35 +03:00
|
|
|
"fmt"
|
|
|
|
"io"
|
|
|
|
"io/ioutil"
|
2019-04-16 12:33:30 +03:00
|
|
|
"os"
|
2020-11-19 00:45:35 +03:00
|
|
|
"path/filepath"
|
2019-04-16 12:33:30 +03:00
|
|
|
"runtime/pprof"
|
|
|
|
"testing"
|
|
|
|
"time"
|
2020-11-19 00:45:35 +03:00
|
|
|
|
|
|
|
"github.com/lightningnetwork/lnd/channeldb"
|
2019-04-16 12:33:30 +03:00
|
|
|
)
|
|
|
|
|
|
|
|
// timeout implements a test level timeout.
|
|
|
|
func timeout(t *testing.T) func() {
|
|
|
|
done := make(chan struct{})
|
|
|
|
go func() {
|
|
|
|
select {
|
|
|
|
case <-time.After(5 * time.Second):
|
|
|
|
pprof.Lookup("goroutine").WriteTo(os.Stdout, 1)
|
|
|
|
|
|
|
|
panic("test timeout")
|
|
|
|
case <-done:
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
|
|
|
|
return func() {
|
|
|
|
close(done)
|
|
|
|
}
|
|
|
|
}
|
2020-11-19 00:45:35 +03:00
|
|
|
|
|
|
|
func copyFile(dest, src string) error {
|
|
|
|
s, err := os.Open(src)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
defer s.Close()
|
|
|
|
|
|
|
|
d, err := os.Create(dest)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
if _, err := io.Copy(d, s); err != nil {
|
|
|
|
d.Close()
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
return d.Close()
|
|
|
|
}
|
|
|
|
|
|
|
|
// copyChannelState copies the OpenChannel state by copying the database and
|
|
|
|
// creating a new struct from it. The copied state and a cleanup function are
|
|
|
|
// returned.
|
|
|
|
func copyChannelState(state *channeldb.OpenChannel) (
|
|
|
|
*channeldb.OpenChannel, func(), error) {
|
|
|
|
|
|
|
|
// Make a copy of the DB.
|
|
|
|
dbFile := filepath.Join(state.Db.Path(), "channel.db")
|
|
|
|
tempDbPath, err := ioutil.TempDir("", "past-state")
|
|
|
|
if err != nil {
|
|
|
|
return nil, nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
cleanup := func() {
|
|
|
|
os.RemoveAll(tempDbPath)
|
|
|
|
}
|
|
|
|
|
|
|
|
tempDbFile := filepath.Join(tempDbPath, "channel.db")
|
|
|
|
err = copyFile(tempDbFile, dbFile)
|
|
|
|
if err != nil {
|
|
|
|
cleanup()
|
|
|
|
return nil, nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
newDb, err := channeldb.Open(tempDbPath)
|
|
|
|
if err != nil {
|
|
|
|
cleanup()
|
|
|
|
return nil, nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
chans, err := newDb.FetchAllChannels()
|
|
|
|
if err != nil {
|
|
|
|
cleanup()
|
|
|
|
return nil, nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
// We only support DBs with a single channel, for now.
|
|
|
|
if len(chans) != 1 {
|
|
|
|
cleanup()
|
|
|
|
return nil, nil, fmt.Errorf("found %d chans in the db",
|
|
|
|
len(chans))
|
|
|
|
}
|
|
|
|
|
|
|
|
return chans[0], cleanup, nil
|
|
|
|
}
|