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

Implement local watcher #182

83 changes: 59 additions & 24 deletions channel/adjudicator.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,41 +25,76 @@ import (
)

type (
// An Adjudicator represents an adjudicator contract on the blockchain. It has
// methods for state registration, progression and withdrawal of channel
// funds. A channel state needs to be registered before it can be progressed
// or withdrawn. No-App channels skip the force-execution phase and can be
// withdrawn directly after the refutation phase has finished. Channels in a
// final state can directly be withdrawn after registration.

// Adjudicator is the interface that groups the Register, Withdraw,
// Progress and Subscribe methods.
//
// An adjudicator represents an adjudicator contract on the blockchain. A
// channel state needs to be registered before it can be progressed or
// withdrawn. No-App channels skip the force-execution phase and can be
// withdrawn directly after the refutation phase has finished. Channels in
// a final state can directly be withdrawn after registration.
//
// Furthermore, an Adjudicator has a method for subscribing to
// AdjudicatorEvents. Those events might be triggered by a Register or
// Progress call on the adjudicator from any channel participant.
Adjudicator interface {
// Register should register the given ledger channel state on-chain.
// If the channel has locked funds into sub-channels, the corresponding
// signed sub-channel states must be provided.
Registerer
Withdrawer
Progresser
EventSubscriber
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be removed. As adjudicator does not make subscriptions.

Copy link
Author

@manoranjith manoranjith Sep 21, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

EventSubscriber removed from Adjudicator, as it not used by the client anymore. (It is used only by the Watcher and Watcher uses the RegisterSubscriber method. See PR #212.

}

// RegisterSubscriber is the interface that groups Register and Subscribe
// methods.
//
// These methods are used to watch for adjudicator events on the blockchain
// and register disputes, if state in the adjudicator event is not the
// latest.
RegisterSubscriber interface {
Registerer
EventSubscriber
}

// Registerer is the interface that wraps the Register method.
//
// Register should register the given ledger channel state on-chain.
// If the channel has locked funds into sub-channels, the corresponding
// signed sub-channel states must be provided.
Registerer interface {
Register(context.Context, AdjudicatorReq, []SignedState) error
}

// Withdraw should conclude and withdraw the registered state, so that the
// final outcome is set on the asset holders and funds are withdrawn
// (dependent on the architecture of the contracts). It must be taken into
// account that a peer might already have concluded the same channel.
// If the channel has locked funds in sub-channels, the states of the
// corresponding sub-channels need to be supplied additionally.
// Withdrawer is the interface that wraps the Withdraw method.
//
// Withdraw should conclude and withdraw the registered state, so that the
// final outcome is set on the asset holders and funds are withdrawn
// (dependent on the architecture of the contracts). It must be taken into
// account that a peer might already have concluded the same channel.
// If the channel has locked funds in sub-channels, the states of the
// corresponding sub-channels need to be supplied additionally.
Withdrawer interface {
Withdraw(context.Context, AdjudicatorReq, StateMap) error
}

// Progress should try to progress an on-chain registered state to the new
// state given in ProgressReq. The Transaction field only needs to
// contain the state, the signatures can be nil, since the old state is
// already registered on the adjudicator.
// Progresser is the interface that wraps the Progress method.
//
// Progress should try to progress an on-chain registered state to the new
// state given in ProgressReq. The Transaction field only needs to
// contain the state, the signatures can be nil, since the old state is
// already registered on the adjudicator.
Progresser interface {
Progress(context.Context, ProgressReq) error
}

// Subscribe returns an AdjudicatorEvent subscription.
//
// The context should only be used to establish the subscription. The
// framework will call Close on the subscription once the respective channel
// controller shuts down.
// EventSubscriber is the interface that wraps the Subscribe method.
//
// Subscribe returns an AdjudicatorEvent subscription.
//
// The context should only be used to establish the subscription. The
// subscription should be closed by calling Close on the subscription after
// the channel is closed.
EventSubscriber interface {
Subscribe(context.Context, ID) (AdjudicatorSubscription, error)
}

Expand Down
18 changes: 18 additions & 0 deletions watcher/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Copyright 2021 - See NOTICE file for copyright holders.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Package watcher contains interface definitions for the watcher.
//
// These interfaces will be implemented by different watcher implementations.
package watcher // import "perun.network/go-perun/watcher"
73 changes: 73 additions & 0 deletions watcher/watcher.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
// Copyright 2021 - See NOTICE file for copyright holders.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package watcher

import (
"context"

"perun.network/go-perun/channel"
)

type (
// Watcher is the interface used by client to interact with the Watcher.
//
// When a new channel is established, the client should register it with
// the watcher by calling the StartWatching method.
//
// After that, it could publish each state on the StatesPub. If any state
// is registered or progressed on the blockchain, the corresponding
// adjudicator event will be relayed by the watcher on the AdjudicatorSub.
// If the registered state is not the latest state (published to the
// watcher) then, the watcher will automatically refute by registering the
// latest state on the blockchain.
//
// Once a channel is closed, client can de-register the channel from the
// watcher by calling the StopWatching API. This will close the
// AdjudicatorSub and StatesSub. Client must not publish states after
// this.
Watcher interface {
StartWatchingLedgerChannel(context.Context, channel.SignedState) (StatesPub, AdjudicatorSub, error)
StartWatchingSubChannel(context.Context, channel.ID, channel.SignedState) (StatesPub, AdjudicatorSub, error)
StopWatching(channel.ID) error
}

// StatesPub is the interface used to send newer off-chain from the client
// to the watcher.
//
// This is initialized when client starts watching for a given channel.
// Client can send each state by calling the publish method.
//
// The publisher will be closed when client requests the watcher to stop
// watching or when there is an error. After the client requests the
// watcher to stop watching, Publish method must not be called.
StatesPub interface {
Publish(channel.Transaction) error
}

// AdjudicatorSub is the interface used to relay the adjudicator events
// from the watcher to the client.
//
// This is initialized when client starts watching for a given channel.
// Client can receive the event via the channel returned by Next method.
//
// This channel will be closed when client requests the watcher to stop
// watching or when there is an error. After the channel is closed, error
// message can be read using the Err method.
AdjudicatorSub interface {
Next() <-chan channel.AdjudicatorEvent

Err() error
}
)