Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Persistence Integratiion #1

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified .assets/00_demo_start.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified .assets/01_bob_alice_panes.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified .assets/02-bob_view_alice_open.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified .assets/03-alice_opens_400.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified .assets/04-alice_bob_wait.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified .assets/05-alice_bob_view_opened_channel.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified .assets/06-alice_10_micropayments_20_each.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified .assets/07-alice_micropayments_done.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified .assets/08-bob_settles.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified .assets/09-show_final_balances.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added .assets/10-alice_bob_restore.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added .assets/11-alice_bob_restore_complete.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
# log files
*.log

# database dir
channel_service/*-db

perun-nervos-demo

# Dependency directories (remove the comment below to include it)
Expand Down
31 changes: 30 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ After a few seconds the transaction is confirmed on-chain and both parties were
Let's use Alice to send ten micropayments of 20 CKBytes per payment to Bob via their channel.

![alice-send-micropayments](./.assets/06-alice_10_micropayments_20_each.png)

****
We can observe the fact that multiple payments were issued by looking at the channels version number, which was incremented by ten, the amount of micropayments issued by Alice.

![micropayments-done](./.assets/07-alice_micropayments_done.png)
Expand All @@ -128,3 +128,32 @@ Now we use Bob to settle the channel.
After a few seconds the channels settlement is confirmed on-chain and we can view the updated balances for Bob and Alice.

![channel-settled](./.assets/09-show_final_balances.png)


## Restore Payment Channel
The database is store locally in `*-db` folders.

Simulate an event of channel service shut down by stopping the channel service and the demo service on the second and third terminals.

Restart the channel-services' terminal again.

```
$ cd ./channel_service
go run .
```

Restart Demo app.

```
./perun-nervos-demo
```

Navigate Restore the channel by selecting the `Restore Channel` button and confirm.

![alice-and-bob-restore-channel](./.assets/10-alice_bob_restore.png)

The old channel will be restored, identified by its ID.

![alice-and-bob-restored-channel](./.assets/11-alice_bob_restore_complete.png)

**Note:** If you want to restart a fresh demo, you will need to delete the database folders `*-db` in `channel_service`
36 changes: 12 additions & 24 deletions channel_service/channel_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,13 @@ import (
"errors"
"fmt"
"log"
"math/rand"
"net"
"os"
"os/signal"
"syscall"
"time"

"github.com/decred/dcrd/dcrec/secp256k1/v4"
"github.com/nervosnetwork/ckb-sdk-go/v2/types"
"github.com/perun-network/perun-libp2p-wire/p2p"
"google.golang.org/grpc"
"perun.network/channel-service/rpc/proto"
"perun.network/channel-service/service"
Expand All @@ -22,6 +19,7 @@ import (
"perun.network/perun-ckb-backend/wallet/address"
"perun.network/perun-ckb-backend/wallet/external"
"perun.network/perun-nervos-demo/deployment"
"polycry.pt/poly-go/sortedkv/leveldb"
)

const (
Expand Down Expand Up @@ -108,35 +106,24 @@ func main() {
aliceWSC := setupWalletServiceClient(aliceWSSURL)
bobWSC := setupWalletServiceClient(bobWSSURL)

wireAccA := p2p.NewRandomAccount(rand.New(rand.NewSource(time.Now().UnixNano())))
wirenetA, err := p2p.NewP2PBus(wireAccA)
// Setup Alice
dbAlice, err := leveldb.LoadDatabase("./alice-db")
if err != nil {
log.Fatalf("creating p2p net: %v", err)
log.Fatalf("loading database: %v", err)
}
go wirenetA.Bus.Listen(wirenetA.Listener)

// AddressRessolver Alice
addrResolverA := service.NewRelayServerResolver(wireAccA)
if !addrResolverA.Address().Equal(wireAccA.Address()) {
log.Fatalf("address resolver address does not match account address")
}

csA, err := service.NewChannelService(nil, wirenetA, network, rpcNodeURL, d, wireAccA.Address(), addrResolverA)
csA, err := service.NewChannelService(aliceWSC, network, rpcNodeURL, d, nil, dbAlice)
if err != nil {
log.Fatalf("creating channel service: %v", err)
}

wireAccB := p2p.NewRandomAccount(rand.New(rand.NewSource(time.Now().UnixNano())))
wirenetB, err := p2p.NewP2PBus(wireAccB)
// Setup Bob
dbBob, err := leveldb.LoadDatabase("./bob-db")
if err != nil {
log.Fatalf("creating p2p net: %v", err)
log.Fatalf("loading database: %v", err)
}
go wirenetB.Bus.Listen(wirenetB.Listener)

// AddressRessolver Alice
addrResolverB := service.NewRelayServerResolver(wireAccB)

csB, err := service.NewChannelService(nil, wirenetB, network, rpcNodeURL, d, wireAccB.Address(), addrResolverB)
csB, err := service.NewChannelService(bobWSC, network, rpcNodeURL, d, nil, dbBob)
if err != nil {
log.Fatalf("creating channel service: %v", err)
}
Expand Down Expand Up @@ -164,6 +151,7 @@ func main() {
// Channel to notify when servers are stopped
done := make(chan bool, 1)

// Handle termination signal in a separate goroutine
go func() {
<-sigs
fmt.Println("Shutting down gRPC servers...")
Expand All @@ -178,15 +166,15 @@ func main() {

// Start the servers
go func() {
fmt.Printf("Starting Alice Channel Service Server at %s\n", hostA)
fmt.Printf("Starting Alice Channel Service Server at %s \n", hostA)
err = sA.Serve(lisA)
if err != nil {
log.Fatalf("serving channel service: %v", err)
}
}()

go func() {
fmt.Printf("Starting Bob Channel Service Server at %s\n", hostB)
fmt.Printf("Starting Bob Channel Service Server at %s \n", hostB)
err = sB.Serve(lisB)
if err != nil {
log.Fatalf("serving channel service: %v", err)
Expand Down
46 changes: 40 additions & 6 deletions client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ type WalletClient struct {
Network types.Network
assetRegister asset2.Register

channelService proto.ChannelServiceClient
ChannelService proto.ChannelServiceClient
WalletServer *wallet_service.MyWalletService
walletService proto.WalletServiceClient

Expand Down Expand Up @@ -97,9 +97,10 @@ func NewWalletClient(
rpcClient: balanceRPC,
walletService: wsc,
WalletServer: wss,
channelService: csc,
ChannelService: csc,
}
wss.SetOnUpdate(p.NotifyAllState)

go p.PollBalances()
return p, nil
}
Expand Down Expand Up @@ -238,7 +239,7 @@ func (p *WalletClient) OpenChannel(peer gpwallet.Address, amounts map[gpchannel.
}

// Use channel service to send proposal
resp, err := p.channelService.OpenChannel(context.Background(), openChannelRequest)
resp, err := p.ChannelService.OpenChannel(context.Background(), openChannelRequest)
if err != nil {
log.Fatalf("Failed to open channel: %v", err)
}
Expand All @@ -253,6 +254,7 @@ func (p *WalletClient) OpenChannel(peer gpwallet.Address, amounts map[gpchannel.
}

func (p *WalletClient) SendPaymentToPeer(amounts map[gpchannel.Asset]float64) {
log.Println("SendPaymentToPeer called")
if !p.HasOpenChannel() {
return
}
Expand Down Expand Up @@ -283,7 +285,8 @@ func (p *WalletClient) SendPaymentToPeer(amounts map[gpchannel.Asset]float64) {
State: protoUpdate,
}

resp, err := p.channelService.UpdateChannel(context.Background(), updateChannelRequest)
log.Println("Sending payment to peer")
resp, err := p.ChannelService.UpdateChannel(context.Background(), updateChannelRequest)
if err != nil {
log.Fatalf("Failed to update channel: %v", err)
}
Expand All @@ -296,6 +299,7 @@ func (p *WalletClient) SendPaymentToPeer(amounts map[gpchannel.Asset]float64) {
}

func (p *WalletClient) Settle() {
log.Println("Settle called")
if !p.HasOpenChannel() {
return
}
Expand All @@ -304,7 +308,7 @@ func (p *WalletClient) Settle() {
ChannelId: p.Channel.State().ID[:],
}

resp, err := p.channelService.CloseChannel(context.Background(), closeChannelRequest)
resp, err := p.ChannelService.CloseChannel(context.Background(), closeChannelRequest)
if err != nil {
log.Fatalf("Failed to close channel: %v", err)
}
Expand All @@ -318,8 +322,38 @@ func (p *WalletClient) Settle() {
}

func (p *WalletClient) RestoreChannel() {
if p.HasOpenChannel() {
if !p.HasOpenChannel() {

// Close Perun Client on Channel Service
log.Println("Closing perun client")
_, err := p.ChannelService.ClosePerunClient(context.Background(), &proto.ClosePerunClientRequest{})
if err != nil {
log.Fatalf("failed to close perun client: %s", err)
}

// Reinit Perun Client on Channel Service
log.Println("Creating perun client")
resp, err := p.ChannelService.NewPerunClient(context.Background(), &proto.NewPerunClientRequest{})
if err != nil {
log.Fatalf("failed to create perun client: %s", err)
}

if !resp.Accepted {
log.Fatalf("perun client creation rejected")
}

log.Println("Restoring channel")
// Restore the channel
resp2, err := p.ChannelService.RestoreChannels(context.Background(), &proto.RestoreChannelsRequest{})
if err != nil {
log.Fatalf("Failed to restore channel: %v", err)
}

if !resp2.Accepted {
log.Fatalf("Channel restore request was rejected")
}
log.Println("Channel restored")

return
}
log.Println("Channel is already online")
Expand Down
12 changes: 7 additions & 5 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,12 @@ go 1.20
require (
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0
github.com/nervosnetwork/ckb-sdk-go/v2 v2.2.0
github.com/perun-network/perun-libp2p-wire v0.0.0-20240604094050-faeb97e75f3c
github.com/stretchr/testify v1.9.0
google.golang.org/grpc v1.59.0
perun.network/channel-service v0.0.0
perun.network/go-perun v0.11.0
perun.network/perun-ckb-backend v0.0.0-20240514141411-35bdf3afa166
perun.network/perun-demo-tui v0.0.0-20240612133942-48e004fee36f
perun.network/perun-demo-tui v0.0.0-20240621081521-af8d85af0f76
polycry.pt/poly-go v0.0.0-20220301085937-fb9d71b45a37
)

Expand All @@ -29,7 +28,8 @@ require (
github.com/gdamore/tcell/v2 v2.6.0 // indirect
github.com/go-ole/go-ole v1.3.0 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect
github.com/google/gopacket v1.1.17 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/gorilla/websocket v1.5.1 // indirect
Expand Down Expand Up @@ -93,6 +93,7 @@ require (
github.com/multiformats/go-multistream v0.2.0 // indirect
github.com/multiformats/go-varint v0.0.6 // indirect
github.com/opentracing/opentracing-go v1.2.0 // indirect
github.com/perun-network/perun-libp2p-wire v0.1.1 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/rivo/tview v0.0.0-20230621164836-6cc0565babaf // indirect
Expand All @@ -103,6 +104,7 @@ require (
github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 // indirect
github.com/spaolacci/murmur3 v1.1.0 // indirect
github.com/stretchr/objx v0.5.2 // indirect
github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // indirect
github.com/tklauser/go-sysconf v0.3.13 // indirect
github.com/tklauser/numcpus v0.7.0 // indirect
github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 // indirect
Expand All @@ -121,10 +123,10 @@ require (
golang.org/x/text v0.14.0 // indirect
golang.org/x/tools v0.17.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20231016165738-49dd2c1f3d0b // indirect
google.golang.org/protobuf v1.31.0 // indirect
google.golang.org/protobuf v1.33.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

replace github.com/nervosnetwork/ckb-sdk-go/v2 v2.2.0 => github.com/perun-network/ckb-sdk-go/v2 v2.2.1-0.20240618093616-6d9d92aa863d

replace perun.network/channel-service v0.0.0 => github.com/perun-network/channel-service v0.0.0-20240619092514-d1880c8fac75
replace perun.network/channel-service v0.0.0 => github.com/perun-network/channel-service v0.0.0-20240627093723-15f145c6c285
Loading