Skip to content

Commit

Permalink
Merge pull request #12 from perun-network/add-processing-stellar-events
Browse files Browse the repository at this point in the history
  • Loading branch information
iljabvh committed Apr 9, 2024
2 parents f5c915e + e47e1ff commit 1266747
Show file tree
Hide file tree
Showing 4 changed files with 356 additions and 92 deletions.
8 changes: 4 additions & 4 deletions channel/subscribe.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ func (s *AdjEventSub) Next() pchannel.AdjudicatorEvent {
case *event.DisputedEvent:
log.Println("DisputedEvent received")
dispEvent := pchannel.AdjudicatorEventBase{
VersionV: e.Version(),
IDV: e.ID(),
VersionV: e.GetVersion(),
IDV: e.GetID(),
TimeoutV: event.MakeTimeout(*s.challengeDuration),
}
ddn := &pchannel.RegisteredEvent{AdjudicatorEventBase: dispEvent, State: nil, Sigs: nil}
Expand All @@ -52,8 +52,8 @@ func (s *AdjEventSub) Next() pchannel.AdjudicatorEvent {

log.Println("CloseEvent received")
conclEvent := pchannel.AdjudicatorEventBase{
VersionV: e.Version(),
IDV: e.ID(),
VersionV: e.GetVersion(),
IDV: e.GetID(),
TimeoutV: event.MakeTimeout(*s.challengeDuration),
}
ccn := &pchannel.ConcludedEvent{AdjudicatorEventBase: conclEvent}
Expand Down
148 changes: 118 additions & 30 deletions client/client.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
// Copyright 2024 PolyCrypt GmbH
//
// 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 client

import (
Expand All @@ -17,6 +31,8 @@ import (

var _ StellarClient = (*Client)(nil)

var ErrCouldNotDecodeTxMeta = errors.New("could not decode tx output")

type Client struct {
hzClient *horizonclient.Client
keyHolder keyHolder
Expand All @@ -43,9 +59,14 @@ func (c *Client) Open(ctx context.Context, perunAddr xdr.ScAddress, params *pcha
return errors.New("error while invoking and processing host function: open")
}

_, err = event.DecodeEventsPerun(txMeta)
evs, err := event.DecodeEventsPerun(txMeta)
if err != nil {
return err
}

err = event.AssertOpenEvent(evs)
if err != nil {
return errors.New("error while decoding events")
return err
}

return nil
Expand All @@ -65,7 +86,7 @@ func (c *Client) Abort(ctx context.Context, perunAddr xdr.ScAddress, state *pcha

_, err = event.DecodeEventsPerun(txMeta)
if err != nil {
return errors.New("error while decoding events")
return err
}

return nil
Expand All @@ -80,12 +101,31 @@ func (c *Client) Fund(ctx context.Context, perunAddr xdr.ScAddress, assetAddr xd

txMeta, err := c.InvokeAndProcessHostFunction("fund", fundTxArgs, perunAddr)
if err != nil {
return errors.New("error while invoking and processing host function: fund")
return err
}

_, err = event.DecodeEventsPerun(txMeta)
evs, err := event.DecodeEventsPerun(txMeta)
if err != nil {
return errors.New("error while decoding events")
return err
}

err = event.AssertFundedEvent(evs)

if err == event.ErrNoFundEvent {
chanFunded, err := c.GetChannelInfo(ctx, perunAddr, chanID)
if err != nil {
return err
}
if chanFunded.Control.FundedA || chanFunded.Control.FundedB {
return nil
} else if chanFunded.Control.FundedA != chanFunded.Control.FundedB {
return nil
} else {
return errors.New("no funding happened after calling fund")
}

} else if err != nil {
return event.ErrNoFundEvent
}

return nil
Expand All @@ -103,12 +143,23 @@ func (c *Client) Close(ctx context.Context, perunAddr xdr.ScAddress, state *pcha
return errors.New("error while invoking and processing host function: close")
}

_, err = event.DecodeEventsPerun(txMeta)
evs, err := event.DecodeEventsPerun(txMeta)
if err != nil {
return errors.New("error while decoding events")
return err
}

return nil
err = event.AssertCloseEvent(evs)
if err == event.ErrNoCloseEvent {
chanInfo, err := c.GetChannelInfo(ctx, perunAddr, state.ID)
if err != nil {
return errors.New("could not get channel info")
}
if chanInfo.Control.Closed {
return nil
}
}

return event.ErrNoCloseEvent
}

func (c *Client) ForceClose(ctx context.Context, perunAddr xdr.ScAddress, chanId pchannel.ID) error {
Expand All @@ -122,10 +173,27 @@ func (c *Client) ForceClose(ctx context.Context, perunAddr xdr.ScAddress, chanId
if err != nil {
return errors.New("error while invoking and processing host function")
}
_, err = event.DecodeEventsPerun(txMeta)
evs, err := event.DecodeEventsPerun(txMeta)
if err != nil {
return errors.New("error while decoding events")
return err
}

err = event.AssertForceCloseEvent(evs)
if err == event.ErrNoForceCloseEvent {
chanInfo, err := c.GetChannelInfo(ctx, perunAddr, chanId)
if err != nil {
return errors.New("could not retrieve channel info")
}
if !chanInfo.Control.Disputed {
return errors.New("force close of a state that is not disputed")
}

if chanInfo.Control.Closed {
return errors.New("force close of a channel that is closed already")
}

}

return nil
}

Expand All @@ -138,42 +206,62 @@ func (c *Client) Dispute(ctx context.Context, perunAddr xdr.ScAddress, state *pc
if err != nil {
return errors.New("error while invoking and processing host function: dispute")
}
_, err = event.DecodeEventsPerun(txMeta)
evs, err := event.DecodeEventsPerun(txMeta)

if err != nil {
return errors.New("error while decoding events")
return err
}

err = event.AssertDisputeEvent(evs)
if err == event.ErrNoDisputeEvent {
chanInfo, err := c.GetChannelInfo(ctx, perunAddr, state.ID)
if err != nil {
return errors.New("could not retrieve channel info")
}
if chanInfo.Control.Disputed || chanInfo.Control.Closed {
return nil
}
} else {
return err
}

return nil
}

func (c *Client) Withdraw(ctx context.Context, perunAddr xdr.ScAddress, req pchannel.AdjudicatorReq) error {
chanIDStellar := req.Tx.State.ID
partyIdx := req.Idx

var withdrawerIdx bool

if partyIdx == 0 {
withdrawerIdx = false
} else if partyIdx == 1 {
withdrawerIdx = true
} else {
chanID, partyIdx := req.Tx.State.ID, req.Idx
withdrawerIdx := partyIdx == 1
if partyIdx > 1 {
return errors.New("invalid party index for withdrawal")
}

withdrawTxArgs, err := buildChanIdxTxArgs(chanIDStellar, withdrawerIdx)
withdrawTxArgs, err := buildChanIdxTxArgs(chanID, withdrawerIdx)
if err != nil {
return errors.New("error while building fund tx")
return errors.New("error building fund tx")
}
txMeta, err := c.InvokeAndProcessHostFunction("withdraw", withdrawTxArgs, perunAddr)
if err != nil {
return errors.New("error while invoking and processing host function: withdraw")
return errors.New("error in host function: withdraw")
}

_, err = event.DecodeEventsPerun(txMeta)
evs, err := event.DecodeEventsPerun(txMeta)
if err != nil {
return errors.New("error while decoding events")
return err
}

return nil
err = event.AssertWithdrawEvent(evs)
if err != event.ErrNoWithdrawEvent {
return err
}

chanInfo, err := c.GetChannelInfo(ctx, perunAddr, chanID)
if err != nil {
return err
}
if (withdrawerIdx && chanInfo.Control.WithdrawnB) || (!withdrawerIdx && chanInfo.Control.WithdrawnA) {
return nil
}

return event.ErrNoWithdrawEvent
}

func (c *Client) GetChannelInfo(ctx context.Context, perunAddr xdr.ScAddress, chanId pchannel.ID) (wire.Channel, error) {
Expand Down
3 changes: 1 addition & 2 deletions client/transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package client

import (
"context"
"errors"
"github.com/creachadair/jrpc2"
"github.com/creachadair/jrpc2/jhttp"
"github.com/stellar/go/clients/horizonclient"
Expand Down Expand Up @@ -75,7 +74,7 @@ func (c *Client) InvokeAndProcessHostFunction(fname string, callTxArgs xdr.ScVec
// Decode transaction metadata
txMeta, err := DecodeTxMeta(tx)
if err != nil {
return xdr.TransactionMeta{}, errors.New("error while decoding tx meta")
return xdr.TransactionMeta{}, ErrCouldNotDecodeTxMeta
}
_ = txMeta.V3.SorobanMeta.ReturnValue

Expand Down
Loading

0 comments on commit 1266747

Please sign in to comment.