Skip to content

Commit

Permalink
Merge pull request #44 from perun-network/fix-for-goperun-0.10.7
Browse files Browse the repository at this point in the history
Restore compatibility between go-perun post-0.10.6 and eth-backend
  • Loading branch information
iljabvh authored Jan 31, 2024
2 parents 5bbe33a + b5f8a7f commit d746e4a
Show file tree
Hide file tree
Showing 12 changed files with 134 additions and 114 deletions.
2 changes: 1 addition & 1 deletion .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ linters-settings:
goheader:
values:
regexp:
ANY_YEAR: "20(19|20|21|22)" # 2019-2022
ANY_YEAR: "20(19|20|21|22|23|24)" # 2019-2024
template-path: .copyright-header
forbidigo:
forbid:
Expand Down
78 changes: 78 additions & 0 deletions channel/app.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// Copyright 2024 - 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 channel

import (
"math/rand"

ethwallet "github.com/perun-network/perun-eth-backend/wallet"
ethtestwallet "github.com/perun-network/perun-eth-backend/wallet/test"
"perun.network/go-perun/channel"
)

var _ channel.AppID = new(AppID)

// AppID described an app identifier.
type AppID struct {
*ethwallet.Address
}

// AppIDKey is the key representation of an app identifier.
type AppIDKey string

// Equal compares two AppID objects for equality.
func (a AppID) Equal(b channel.AppID) bool {
bTyped, ok := b.(*AppID)
if !ok {
return false
}
return a.Address.Equal(bTyped.Address)
}

// Key returns the key representation of this app identifier.
func (a AppID) Key() channel.AppIDKey {
b, err := a.MarshalBinary()
if err != nil {
panic(err)
}
return channel.AppIDKey(b)
}

// MarshalBinary marshals the contents of AppID into a byte string.
func (a AppID) MarshalBinary() ([]byte, error) {
data, err := a.Address.MarshalBinary()
if err != nil {
return nil, err
}
return data, nil
}

// UnmarshalBinary converts a bytestring, representing AppID into the AppID struct.
func (a *AppID) UnmarshalBinary(data []byte) error {
addr := &ethwallet.Address{}
err := addr.UnmarshalBinary(data)
if err != nil {
return err
}
appaddr := &AppID{addr}
*a = *appaddr
return nil
}

// NewRandomAppID calls NewRandomAddress to generate a random Ethereum test address.
func NewRandomAppID(rng *rand.Rand) *AppID {
addr := ethtestwallet.NewRandomAddress(rng)
return &AppID{&addr}
}
12 changes: 11 additions & 1 deletion channel/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,12 @@ func (*Backend) CalcID(p *channel.Params) (id channel.ID) {
return CalcID(p)
}

// NewAppID creates a new app identifier, using an empty ethereum struct.
func (b *Backend) NewAppID() channel.AppID {
addr := &ethwallet.Address{}
return &AppID{addr}
}

// Sign signs the channel state as needed by the ethereum smart contracts.
func (*Backend) Sign(acc wallet.Account, s *channel.State) (wallet.Sig, error) {
return Sign(acc, s)
Expand Down Expand Up @@ -152,7 +158,11 @@ func Verify(addr wallet.Address, s *channel.State, sig wallet.Sig) (bool, error)
func ToEthParams(p *channel.Params) adjudicator.ChannelParams {
var app common.Address
if p.App != nil && !channel.IsNoApp(p.App) {
app = ethwallet.AsEthAddr(p.App.Def())
appDef, ok := p.App.Def().(*AppID)
if !ok {
panic("appDef is not of type *AppID")
}
app = ethwallet.AsEthAddr(appDef.Address)
}

return adjudicator.ChannelParams{
Expand Down
81 changes: 3 additions & 78 deletions channel/conclude.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,16 @@ import (
"context"
"fmt"

"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/core/types"
"github.com/pkg/errors"

"github.com/perun-network/perun-eth-backend/bindings"
"github.com/perun-network/perun-eth-backend/bindings/adjudicator"
cherrors "github.com/perun-network/perun-eth-backend/channel/errors"
"github.com/perun-network/perun-eth-backend/subscription"
"github.com/pkg/errors"
"perun.network/go-perun/channel"
"perun.network/go-perun/log"
)

const (
secondaryWaitBlocks = 2
adjEventBuffSize = 10
adjHeaderBuffSize = 10
adjEventBuffSize = 10
)

// ensureConcluded ensures that conclude or concludeFinal (for non-final and
Expand All @@ -51,16 +45,8 @@ func (a *Adjudicator) ensureConcluded(ctx context.Context, req channel.Adjudicat
return nil
}

// If the secondary flag is set, we wait for someone else to conclude.
concluded, err := a.waitConcludedSecondary(ctx, req)
if err != nil {
return errors.WithMessage(err, "waiting for secondary conclude")
} else if concluded {
return nil
}

// Wait until we can conclude.
err = a.waitConcludable(ctx, req)
err := a.waitConcludable(ctx, req)
if err != nil {
return fmt.Errorf("waiting for concludability: %w", err)
}
Expand Down Expand Up @@ -160,25 +146,6 @@ func (a *Adjudicator) checkConcludedState(
}
}

func (a *Adjudicator) waitConcludedSecondary(ctx context.Context, req channel.AdjudicatorReq) (concluded bool, err error) {
// In final Register calls, as the non-initiator, we optimistically wait for
// the other party to send the transaction first for
// `secondaryWaitBlocks + TxFinalityDepth` many blocks.
if req.Tx.IsFinal && req.Secondary {
// Create subscription.
sub, events, subErr, err := a.createEventSub(ctx, req.Tx.ID, false)
if err != nil {
return false, errors.WithMessage(err, "subscribing")
}
defer sub.Close()

// Wait for concluded event.
waitBlocks := secondaryWaitBlocks + int(a.txFinalityDepth)
return waitConcludedForNBlocks(ctx, a, events, subErr, waitBlocks)
}
return false, nil
}

func (a *Adjudicator) conclude(ctx context.Context, req channel.AdjudicatorReq, subStates channel.StateMap) error {
// If the on-chain state resulted from forced execution, we do not have a fully-signed state and cannot call concludeFinal.
forceExecuted, err := a.isForceExecuted(ctx, req.Params.ID())
Expand Down Expand Up @@ -335,45 +302,3 @@ func updateEventType(channelID [32]byte) subscription.EventFactory {
}
}
}

// waitConcludedForNBlocks waits for up to numBlocks blocks for a Concluded
// event on the concluded channel. If an event is emitted, true is returned.
// Otherwise, if numBlocks blocks have passed, false is returned.
//
// cr is the ChainReader used for setting up a block header subscription. sub is
// the Concluded event subscription instance.
func waitConcludedForNBlocks(ctx context.Context,
cr ethereum.ChainReader,
concluded <-chan *subscription.Event,
subErr <-chan error,
numBlocks int,
) (bool, error) {
h := make(chan *types.Header, adjHeaderBuffSize)
hsub, err := cr.SubscribeNewHead(ctx, h)
if err != nil {
err = cherrors.CheckIsChainNotReachableError(err)
return false, errors.WithMessage(err, "subscribing to new blocks")
}
defer hsub.Unsubscribe()
for i := 0; i < numBlocks; i++ {
select {
case <-h: // do nothing, wait another block
case _e := <-concluded: // other participant performed transaction
e, ok := _e.Data.(*adjudicator.AdjudicatorChannelUpdate)
if !ok {
log.Panic("wrong event type")
}
if e.Phase == phaseConcluded {
return true, nil
}
case <-ctx.Done():
return false, errors.Wrap(ctx.Err(), "context cancelled")
case err = <-hsub.Err():
err = cherrors.CheckIsChainNotReachableError(err)
return false, errors.WithMessage(err, "header subscription error")
case err = <-subErr:
return false, errors.WithMessage(err, "event subscription error")
}
}
return false, nil
}
40 changes: 14 additions & 26 deletions channel/conclude_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,28 +71,18 @@ func testConcludeFinal(t *testing.T, numParts int) {
ctx, cancel := context.WithTimeout(context.Background(), defaultTxTimeout)
defer cancel()
ct = pkgtest.NewConcurrent(t)
initiator := int(rng.Int31n(int32(numParts))) // pick a random initiator
for i := 0; i < numParts; i++ {
i := i
go ct.StageN("register", numParts, func(t pkgtest.ConcT) {
req := channel.AdjudicatorReq{
Params: params,
Acc: s.Accs[i],
Idx: channel.Index(i),
Tx: tx,
Secondary: (i != initiator),
Params: params,
Acc: s.Accs[i],
Idx: channel.Index(i),
Tx: tx,
}
diff, err := test.NonceDiff(s.Accs[i].Address(), s.Adjs[i], func() error {
return s.Adjs[i].Register(ctx, req, nil)
})
err := s.Adjs[i].Register(ctx, req, nil)

require.NoError(t, err, "Withdrawing should succeed")
if !req.Secondary {
// The Initiator must send a TX.
require.Equal(t, diff, 1)
} else {
// Everyone else must NOT send a TX.
require.Equal(t, diff, 0)
}
})
}
ct.Wait("register")
Expand Down Expand Up @@ -254,11 +244,10 @@ func register(ctx context.Context, adj *test.SimAdjudicator, accounts []*keystor
}

req := channel.AdjudicatorReq{
Params: ch.params,
Acc: accounts[0],
Idx: 0,
Tx: tx,
Secondary: false,
Params: ch.params,
Acc: accounts[0],
Idx: 0,
Tx: tx,
}
return adj.Register(ctx, req, sub)
}
Expand All @@ -277,11 +266,10 @@ func withdraw(ctx context.Context, adj *test.SimAdjudicator, accounts []*keystor

for i, a := range accounts {
req := channel.AdjudicatorReq{
Params: c.params,
Acc: a,
Idx: channel.Index(i),
Tx: tx,
Secondary: i != 0,
Params: c.params,
Acc: a,
Idx: channel.Index(i),
Tx: tx,
}

if err := adj.Withdraw(ctx, req, subStates); err != nil {
Expand Down
14 changes: 10 additions & 4 deletions channel/subscription.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,18 +172,20 @@ func (a *Adjudicator) convertEvent(ctx context.Context, e *adjudicator.Adjudicat
if err != nil {
return nil, errors.WithMessage(err, "fetching call data")
}

ch, ok := args.signedState(e.ChannelID)
if !ok {
return nil, errors.Errorf("channel not found in calldata: %v", e.ChannelID)
}

var app channel.App
var zeroAddress common.Address
if ch.Params.App == zeroAddress {
app = channel.NoApp()
} else {
app, err = channel.Resolve(wallet.AsWalletAddr(ch.Params.App))
appAddr := wallet.AsWalletAddr(ch.Params.App)
appID := &AppID{
Address: appAddr,
}
app, err = channel.Resolve(appID)
if err != nil {
return nil, err
}
Expand All @@ -201,7 +203,11 @@ func (a *Adjudicator) convertEvent(ctx context.Context, e *adjudicator.Adjudicat
if err != nil {
return nil, errors.WithMessage(err, "fetching call data")
}
app, err := channel.Resolve(wallet.AsWalletAddr(args.Params.App))
appAddr := wallet.AsWalletAddr(args.Params.App)
appID := &AppID{
Address: appAddr,
}
app, err := channel.Resolve(appID)
if err != nil {
return nil, errors.WithMessage(err, "resolving app")
}
Expand Down
3 changes: 1 addition & 2 deletions channel/test/adjudicator.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,8 @@ import (

"github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/common"
"github.com/pkg/errors"

ethchannel "github.com/perun-network/perun-eth-backend/channel"
"github.com/pkg/errors"

"perun.network/go-perun/channel"
"perun.network/go-perun/log"
Expand Down
7 changes: 7 additions & 0 deletions channel/test/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,16 @@
package test

import (
"math/rand"

"github.com/perun-network/perun-eth-backend/channel"
pchannel "perun.network/go-perun/channel"
"perun.network/go-perun/channel/test"
)

func init() {
test.SetRandomizer(new(randomizer))
test.SetNewRandomAppID(func(r *rand.Rand) pchannel.AppID {
return channel.NewRandomAppID(r)
})
}
1 change: 1 addition & 0 deletions channel/withdraw_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ func TestWithdrawZeroBalance(t *testing.T) {
}

// shouldFunders decides who should fund. 1 indicates funding, 0 indicates skipping.

//nolint:thelper // Not a helper.
func testWithdrawZeroBalance(t *testing.T, n int) {
rng := pkgtest.Prng(t)
Expand Down
4 changes: 3 additions & 1 deletion client/app_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,9 @@ func TestProgression(t *testing.T) {
}

appAddress := deployMockApp(t, backendSetup)
app := channel.NewMockApp(appAddress)
appAddrBackend := appAddress.(*ethwallet.Address)
appID := &ethchannel.AppID{Address: appAddrBackend}
app := channel.NewMockApp(appID)
channel.RegisterApp(app)

execConfig := &clienttest.ProgressionExecConfig{
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ require (
github.com/sirupsen/logrus v1.8.1
github.com/stretchr/testify v1.7.0
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
perun.network/go-perun v0.10.5
perun.network/go-perun v0.10.7-0.20240115114750-da863c83cb9f
polycry.pt/poly-go v0.0.0-20220301085937-fb9d71b45a37
)

Expand Down
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -653,6 +653,10 @@ honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt
honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las=
perun.network/go-perun v0.10.5 h1:bIaAoLLh8R+RXdPh+MkCJcbtumsFkNvoVAJwb60JKjg=
perun.network/go-perun v0.10.5/go.mod h1:BGBZC3npkX457u87pjDd0NEIXr1a4dsH4H/YpLdGGe8=
perun.network/go-perun v0.10.7-0.20230808153546-74844191e56e h1:4SOKO0WZtcsQUwP5nKVUrLUohgUPIhMa8wto5iNCA/k=
perun.network/go-perun v0.10.7-0.20230808153546-74844191e56e/go.mod h1:BGBZC3npkX457u87pjDd0NEIXr1a4dsH4H/YpLdGGe8=
perun.network/go-perun v0.10.7-0.20240115114750-da863c83cb9f h1:suN6qyoBSBuNBirStAtX+5gIc3tplHzbdB1H+RWlRTc=
perun.network/go-perun v0.10.7-0.20240115114750-da863c83cb9f/go.mod h1:BGBZC3npkX457u87pjDd0NEIXr1a4dsH4H/YpLdGGe8=
polycry.pt/poly-go v0.0.0-20220222131629-aa4bdbaab60b/go.mod h1:XUBrNtqgEhN3EEOP/5gh7IBd3xVHKidCjXDZfl9+kMU=
polycry.pt/poly-go v0.0.0-20220301085937-fb9d71b45a37 h1:iA5GzEa/hHfVlQpimEjPV09NATwHXxSjWNB0VVodtew=
polycry.pt/poly-go v0.0.0-20220301085937-fb9d71b45a37/go.mod h1:XUBrNtqgEhN3EEOP/5gh7IBd3xVHKidCjXDZfl9+kMU=
Expand Down

0 comments on commit d746e4a

Please sign in to comment.