Skip to content

Commit 99867bb

Browse files
authored
Merge branch 'main' into draft/egoistic-funding
2 parents 4c96443 + 3c47eab commit 99867bb

File tree

2 files changed

+118
-1
lines changed

2 files changed

+118
-1
lines changed

channel/funder_test.go

+50-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright 2019 - See NOTICE file for copyright holders.
1+
// Copyright 2024 - See NOTICE file for copyright holders.
22
//
33
// Licensed under the Apache License, Version 2.0 (the "License");
44
// you may not use this file except in compliance with the License.
@@ -16,6 +16,8 @@ package channel_test
1616

1717
import (
1818
"context"
19+
"fmt"
20+
"math"
1921
"math/big"
2022
"math/rand"
2123
"testing"
@@ -194,6 +196,53 @@ func testFunderCrossOverFunding(t *testing.T, n int) {
194196
assert.NoError(t, compareOnChainAlloc(ctx, params, agreement, alloc.Assets, &funders[0].ContractBackend))
195197
}
196198

199+
func TestEgoisticParticipantFunding(t *testing.T) {
200+
// Peers will randomly fund for each other.
201+
for i := 0; i < 30; i++ {
202+
name := fmt.Sprintf("Egoistic Funding %v", i)
203+
t.Run(name, func(t *testing.T) { testEgoisticParticipantFunding(t) })
204+
}
205+
}
206+
207+
func testEgoisticParticipantFunding(t *testing.T) {
208+
t.Helper()
209+
t.Parallel()
210+
n := 2
211+
rng := pkgtest.Prng(t, n)
212+
EgoisticTxTimeout := 20 * time.Second
213+
ctx, cancel := context.WithTimeout(context.Background(), EgoisticTxTimeout*time.Duration(n))
214+
defer cancel()
215+
_, funders, params, alloc := newNFunders(ctx, t, rng, n)
216+
egoisticIndex := rng.Intn(2)
217+
balances := [][]*big.Int{
218+
{big.NewInt(1), big.NewInt(0)},
219+
{big.NewInt(0), big.NewInt(2)},
220+
}
221+
allocation := channel.Allocation{Assets: alloc.Assets, Balances: balances, Locked: alloc.Locked}
222+
egoisticParts := make([]bool, n)
223+
funders[egoisticIndex].SetEgoisticPart(channel.Index(egoisticIndex), n)
224+
egoisticParts[egoisticIndex] = true
225+
t.Logf("Egoistic Participants: %v", egoisticParts)
226+
agreement := allocation.Balances
227+
require.Equal(t, agreement.Sum(), allocation.Balances.Sum())
228+
229+
fundingRequests := make([]*channel.FundingReq, n)
230+
for i := range funders {
231+
req := channel.NewFundingReq(params, &channel.State{Allocation: allocation}, channel.Index(i), agreement)
232+
fundingRequests[i] = req
233+
}
234+
finishTimes, err := test.FundAll(ctx, t, funders, fundingRequests, egoisticIndex)
235+
require.True(t, len(finishTimes) == n, "Length of indexes must be n")
236+
require.NoError(t, err)
237+
238+
t.Logf("finishTimes: %v", finishTimes)
239+
// Check if finish time of egoistic funder is larger than finish time of non-egoistic funder.
240+
correct := finishTimes[egoisticIndex].Time > finishTimes[int(math.Abs(float64(1-egoisticIndex)))].Time
241+
// Use require.True to compare the finish times
242+
require.True(t, correct, "Non-egoistic funders finish earlier than egoistic funders")
243+
assert.NoError(t, compareOnChainAlloc(ctx, params, agreement, allocation.Assets, &funders[0].ContractBackend))
244+
}
245+
197246
func TestFunder_ZeroBalance(t *testing.T) {
198247
t.Run("1 Participant", func(t *testing.T) { testFunderZeroBalance(t, 1) })
199248
t.Run("2 Participant", func(t *testing.T) { testFunderZeroBalance(t, 2) })

channel/test/fund.go

+68
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
// Copyright 2024 - See NOTICE file for copyright holders.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package test
16+
17+
import (
18+
"context"
19+
"sync"
20+
"testing"
21+
"time"
22+
23+
"github.com/perun-network/perun-eth-backend/channel"
24+
"github.com/stretchr/testify/require"
25+
pchannel "perun.network/go-perun/channel"
26+
)
27+
28+
// waitTime is the time to wait before funding a channel when the funder is not egoistic.
29+
const waitTime = 2 * time.Second
30+
31+
// FunderFinishTime is the returned type of FundAll which includes the process time of each funder.
32+
type FunderFinishTime struct {
33+
Index int
34+
Time time.Duration
35+
}
36+
37+
// FundAll calls fund for all funders simultaneously.
38+
func FundAll(ctx context.Context, t *testing.T, funders []*channel.Funder, reqs []*pchannel.FundingReq, egoisticIndex int) ([]FunderFinishTime, error) {
39+
t.Helper()
40+
finishTimes := make([]FunderFinishTime, len(funders))
41+
var mutex sync.Mutex
42+
43+
var wg sync.WaitGroup
44+
wg.Add(len(funders))
45+
46+
for i := range funders {
47+
i := i
48+
go func() {
49+
defer wg.Done()
50+
if i != egoisticIndex {
51+
time.Sleep(waitTime)
52+
}
53+
startTime := time.Now()
54+
err := funders[i].Fund(ctx, *reqs[i])
55+
require.NoError(t, err)
56+
finishTime := time.Now()
57+
mutex.Lock()
58+
finishTimes[i] = FunderFinishTime{
59+
Index: i,
60+
Time: finishTime.Sub(startTime),
61+
}
62+
mutex.Unlock()
63+
}()
64+
}
65+
66+
wg.Wait()
67+
return finishTimes, nil
68+
}

0 commit comments

Comments
 (0)