Skip to content

Commit

Permalink
Remove channelID map (#413)
Browse files Browse the repository at this point in the history
* feat(wallet, channel): Change backend to map of backends
feat(Asset, Adjudicator): Add AssetID struct to identify assets with LedgerID and BackendID
feat(persistence, wire): Use map[int]Address to identify clients

Signed-off-by: Sophia Koehler <[email protected]>

* fix(multi): Add AssetIDKey struct to fix the map lookups for funders and adjudicators.
fix(randomizer): Lookup backend opts to correctly initialize address maps.
fix(test): Generalize tests to be used in other backends.

Signed-off-by: Sophia Koehler <[email protected]>

* fix(all): Use map[int]ID instead of id for each backend.

Signed-off-by: Sophia Koehler <[email protected]>

* fix(all): Add map of IDs

Signed-off-by: Sophia Koehler <[email protected]>

* fix(channel/backend): Revert change in verify.
fix(wallet/wallet, wallet/account): Revert changed definition.
feat(client): Add wallet map to client for each backend.

Signed-off-by: Sophia Koehler <[email protected]>

* fix(Adjudicator): Change to singular channel ID in events.

Signed-off-by: Sophia Koehler <[email protected]>

* fix(client/test): Generalize role test.

Signed-off-by: Sophia Koehler <[email protected]>

* feat(channel): Add backend field check.
feat(client/test, wire): Add backendID arguments.

Signed-off-by: Sophia Koehler <[email protected]>

* fix(subchannel_dispute): Generalize event watcher.

Signed-off-by: Sophia Koehler <[email protected]>

* feat: Asset Address function to handle encoding in backends.

Signed-off-by: Sophia Koehler <[email protected]>

* feat(apps/payment, backend/sim, channel/test, client/test, log, wallet, ): Specify backend for randomizers
feat(channel/multi): Change AssetID to interface
feat(channel/persistence, client/test): Generalize test for backends

Signed-off-by: Sophia Koehler <[email protected]>

* fix(asset.go, allocation.go): Adjust Address() to return byte[] instead of string.
fix(params.go): Change IDKey to encode map entries sorted by keys.
fix(backend.go): Use BackendID in argument to sign depending on backend.
fix(address.go): Sort Addresses by keys before adding them to Keys.

Signed-off-by: Sophia Koehler <[email protected]>

* chore: Remove unnecessary logs

Signed-off-by: Sophia Koehler <[email protected]>

* fix: Remove repeated assetIDs in LedgerID array

Signed-off-by: Sophia Koehler <[email protected]>

* chore: update go.sum, gofmt some files

Signed-off-by: Sophia Koehler <[email protected]>

* fix(wallet/backend.go): Return just one error instead of concatenation of errors
chore(All): Run gofmt and sort imports

Signed-off-by: Sophia Koehler <[email protected]>

* fix(golangci.yml): Exclude generated file from linter
chore: Refactor for linter

Signed-off-by: Sophia Koehler <[email protected]>

* fix(ci): Use go1.18 for the any type in proto
fix(golangci): Fix structure

Signed-off-by: Sophia Koehler <[email protected]>

* fix(ci): Use glinter 1.45 which supports go1.18

Signed-off-by: Sophia Koehler <[email protected]>

* chore(all): Add nolint flags for conversions

Signed-off-by: Sophia Koehler <[email protected]>

* chore(all): remove unnecessary flags

Signed-off-by: Sophia Koehler <[email protected]>

* chore(all): remove unnecessary flags

Signed-off-by: Sophia Koehler <[email protected]>

* chore(all): remove unnecessary flags

Signed-off-by: Sophia Koehler <[email protected]>

* chore(all): remove unnecessary flags

Signed-off-by: Sophia Koehler <[email protected]>

* chore(all): remove unnecessary flags

Signed-off-by: Sophia Koehler <[email protected]>

* chore(all): remove unnecessary flags

Signed-off-by: Sophia Koehler <[email protected]>

* chore(all): remove unnecessary flags

Signed-off-by: Sophia Koehler <[email protected]>

* chore(all): Rename and add comments to exported functions

Signed-off-by: Sophia Koehler <[email protected]>

* chore: Rename variables

Signed-off-by: Sophia Koehler <[email protected]>

* fix(params, address): Fix index allocation

Signed-off-by: Sophia Koehler <[email protected]>

* Revert "fix(all): Add map of IDs"
Revert "fix(all): Use map[int]ID instead of id for each backend."

This reverts commit ab8e60b and ef11de9

Signed-off-by: Sophia Koehler <[email protected]>

* fix(backend.go): Remove unnecessary errors.join()

Signed-off-by: Sophia Koehler <[email protected]>

* fix: remove unnecessary else statement, add linter flag

Signed-off-by: Sophia Koehler <[email protected]>

* refactor(/apps/payment, /sim/wallet, /channel, /client, /wallet, /wire): Name test backend ID in tests
refactor(/multi, /client/test): Rename AssetID to MultiLedgerID

Signed-off-by: Sophia Koehler <[email protected]>

* chore: Update proto binding, remove IDMap

Signed-off-by: Sophia Koehler <[email protected]>

* refactor: Name TestBackendID, rename multiLedgerID to LedgerBackendID

Signed-off-by: Sophia Koehler <[email protected]>

* refactor: Fix comment on exported function

Signed-off-by: Sophia Koehler <[email protected]>

* chore(all): Update license dates

Signed-off-by: Sophia Koehler <[email protected]>

* chore(backendtest): Rename to fix import issues

Signed-off-by: Sophia Koehler <[email protected]>

* fix(allocation_test): Remove channelID map from merge
fix(wire.pb.go): go fmt

Signed-off-by: Sophia Koehler <[email protected]>

* fix(all): Fix errors from merge

Signed-off-by: Sophia Koehler <[email protected]>

* chore(client_role_test): format file

Signed-off-by: Sophia Koehler <[email protected]>

* chore: fix merge errors

Signed-off-by: Sophia Koehler <[email protected]>

---------

Signed-off-by: Sophia Koehler <[email protected]>
  • Loading branch information
sophia1ch authored Feb 11, 2025
1 parent b53c36b commit 7af28d5
Show file tree
Hide file tree
Showing 57 changed files with 773 additions and 1,174 deletions.
4 changes: 2 additions & 2 deletions backend/sim/wallet/address.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,13 +63,13 @@ func NewRandomAddress(rng io.Reader) *Address {

// NewRandomAddresses creates a new address using the randomness
// provided by rng.
func NewRandomAddresses(rng io.Reader) map[int]wallet.Address {
func NewRandomAddresses(rng io.Reader) map[wallet.BackendID]wallet.Address {
privateKey, err := ecdsa.GenerateKey(curve, rng)
if err != nil {
log.Panicf("Creation of account failed with error", err)
}

return map[int]wallet.Address{channel.TestBackendID: &Address{
return map[wallet.BackendID]wallet.Address{channel.TestBackendID: &Address{
Curve: privateKey.Curve,
X: privateKey.X,
Y: privateKey.Y,
Expand Down
9 changes: 4 additions & 5 deletions channel/adjudicator.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ type (
// subscription should be closed by calling Close on the subscription after
// the channel is closed.
EventSubscriber interface {
Subscribe(context.Context, map[wallet.BackendID]ID) (AdjudicatorSubscription, error)
Subscribe(context.Context, ID) (AdjudicatorSubscription, error)
}

// An AdjudicatorReq collects all necessary information to make calls to the
Expand Down Expand Up @@ -204,7 +204,7 @@ type (
}

// StateMap represents a channel state tree.
StateMap map[string]*State
StateMap map[ID]*State
)

// NewProgressReq creates a new ProgressReq object.
Expand Down Expand Up @@ -302,13 +302,12 @@ func (t *TimeTimeout) String() string {

// MakeStateMap creates a new StateMap object.
func MakeStateMap() StateMap {
return make(map[string]*State)
return make(map[ID]*State)
}

// Add adds the given states to the state map.
func (m StateMap) Add(states ...*State) {
for _, s := range states {
key := IDKey(s.ID)
m[key] = s
m[s.ID] = s
}
}
14 changes: 7 additions & 7 deletions channel/allocation.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ type (
// The size of the balances slice must be of the same size as the assets slice
// of the channel Params.
SubAlloc struct {
ID map[wallet.BackendID]ID
ID ID
Bals []Bal
IndexMap []Index // Maps participant indices of the sub-channel to participant indices of the parent channel.
}
Expand Down Expand Up @@ -552,7 +552,7 @@ func (b Balances) Sum() []Bal {
}

// NewSubAlloc creates a new sub-allocation.
func NewSubAlloc(id map[wallet.BackendID]ID, bals []Bal, indexMap []Index) *SubAlloc {
func NewSubAlloc(id ID, bals []Bal, indexMap []Index) *SubAlloc {
if indexMap == nil {
indexMap = []Index{}
}
Expand All @@ -561,9 +561,9 @@ func NewSubAlloc(id map[wallet.BackendID]ID, bals []Bal, indexMap []Index) *SubA

// SubAlloc tries to return the sub-allocation for the given subchannel.
// The second return value indicates success.
func (a Allocation) SubAlloc(subchannel map[wallet.BackendID]ID) (subAlloc SubAlloc, ok bool) {
func (a Allocation) SubAlloc(subchannel ID) (subAlloc SubAlloc, ok bool) {
for _, subAlloc = range a.Locked {
if EqualIDs(subAlloc.ID, subchannel) {
if subAlloc.ID == subchannel {
ok = true
return
}
Expand Down Expand Up @@ -667,7 +667,7 @@ func (s SubAlloc) Encode(w io.Writer) error {
err, "invalid sub-allocations cannot be encoded, got %v", s)
}
// encode ID and dimension
if err := perunio.Encode(w, IDMap(s.ID), Index(len(s.Bals))); err != nil {
if err := perunio.Encode(w, s.ID, Index(len(s.Bals))); err != nil {
return errors.WithMessagef(
err, "encoding sub-allocation ID or dimension, id %v", s.ID)
}
Expand Down Expand Up @@ -696,7 +696,7 @@ func (s SubAlloc) Encode(w io.Writer) error {
func (s *SubAlloc) Decode(r io.Reader) error {
var numAssets Index
// decode ID and dimension
if err := perunio.Decode(r, (*IDMap)(&s.ID), &numAssets); err != nil {
if err := perunio.Decode(r, &s.ID, &numAssets); err != nil {
return errors.WithMessage(err, "decoding sub-allocation ID or dimension")
}
if numAssets > MaxNumAssets {
Expand Down Expand Up @@ -731,7 +731,7 @@ func (s *SubAlloc) Equal(t *SubAlloc) error {
if s == t {
return nil
}
if !EqualIDs(s.ID, t.ID) {
if s.ID != t.ID {
return errors.New("different ID")
}
if !s.BalancesEqual(t.Bals) {
Expand Down
18 changes: 9 additions & 9 deletions channel/allocation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -291,12 +291,12 @@ func TestAllocationValidLimits(t *testing.T) {

for i := range allocation.Locked {
allocation.Locked[i] = *channel.NewSubAlloc(
map[wallet.BackendID]channel.ID{channel.TestBackendID: {byte(i), byte(i >> 8), byte(i >> 16), byte(i >> 24)}},
channel.ID{byte(i), byte(i >> 8), byte(i >> 16), byte(i >> 24)},
make([]channel.Bal, x.numAssets),
nil,
)
allocation.Locked[i] = *channel.NewSubAlloc(
map[wallet.BackendID]channel.ID{channel.TestBackendID: {byte(i), byte(i >> 8), byte(i >> 16), byte(i >> 24)}},
channel.ID{byte(i), byte(i >> 8), byte(i >> 16), byte(i >> 24)},
make([]channel.Bal, x.numAssets),
nil,
)
Expand Down Expand Up @@ -387,7 +387,7 @@ func TestAllocation_Sum(t *testing.T) {

{
"single asset/one participants/one locked",
*test.NewRandomAllocation(rng, test.WithNumAssets(1), test.WithNumParts(1), test.WithLocked(*channel.NewSubAlloc(map[wallet.BackendID]channel.ID{}, []channel.Bal{big.NewInt(2)}, nil)), test.WithBalancesInRange(big.NewInt(1), big.NewInt(1))),
*test.NewRandomAllocation(rng, test.WithNumAssets(1), test.WithNumParts(1), test.WithLocked(*channel.NewSubAlloc(channel.ID{}, []channel.Bal{big.NewInt(2)}, nil)), test.WithBalancesInRange(big.NewInt(1), big.NewInt(1))),
[]channel.Bal{big.NewInt(3)},
},

Expand Down Expand Up @@ -500,7 +500,7 @@ func TestAllocation_Valid(t *testing.T) {
{big.NewInt(64), big.NewInt(128)},
},
Locked: []channel.SubAlloc{
*channel.NewSubAlloc(map[wallet.BackendID]channel.ID{channel.TestBackendID: channel.Zero}, []channel.Bal{big.NewInt(4)}, nil),
*channel.NewSubAlloc(channel.Zero, []channel.Bal{big.NewInt(4)}, nil),
},
},
false,
Expand All @@ -516,7 +516,7 @@ func TestAllocation_Valid(t *testing.T) {
{big.NewInt(64), big.NewInt(128)},
},
Locked: []channel.SubAlloc{
*channel.NewSubAlloc(map[wallet.BackendID]channel.ID{channel.TestBackendID: channel.Zero}, []channel.Bal{big.NewInt(-1)}, nil),
*channel.NewSubAlloc(channel.Zero, []channel.Bal{big.NewInt(-1)}, nil),
},
},
false,
Expand Down Expand Up @@ -544,7 +544,7 @@ func TestAllocation_Valid(t *testing.T) {
{big.NewInt(2), big.NewInt(16)},
},
Locked: []channel.SubAlloc{
*channel.NewSubAlloc(map[wallet.BackendID]channel.ID{channel.TestBackendID: channel.Zero}, []channel.Bal{big.NewInt(4), big.NewInt(-1)}, nil),
*channel.NewSubAlloc(channel.Zero, []channel.Bal{big.NewInt(4), big.NewInt(-1)}, nil),
},
},
false,
Expand All @@ -564,9 +564,9 @@ func TestAllocation_Valid(t *testing.T) {
// suballocation serialization.
func TestSuballocSerialization(t *testing.T) {
ss := []perunio.Serializer{
channel.NewSubAlloc(map[wallet.BackendID]channel.ID{channel.TestBackendID: {2}}, []channel.Bal{}, nil),
channel.NewSubAlloc(map[wallet.BackendID]channel.ID{channel.TestBackendID: {3}}, []channel.Bal{big.NewInt(0)}, nil),
channel.NewSubAlloc(map[wallet.BackendID]channel.ID{channel.TestBackendID: {4}}, []channel.Bal{big.NewInt(5), big.NewInt(1 << 62)}, nil),
channel.NewSubAlloc(channel.ID{2}, []channel.Bal{}, nil),
channel.NewSubAlloc(channel.ID{3}, []channel.Bal{big.NewInt(0)}, nil),
channel.NewSubAlloc(channel.ID{4}, []channel.Bal{big.NewInt(5), big.NewInt(1 << 62)}, nil),
}

peruniotest.GenericSerializerTest(t, ss...)
Expand Down
21 changes: 13 additions & 8 deletions channel/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,16 +64,21 @@ func SetBackend(b Backend, id int) {
}

// CalcID calculates the CalcID.
func CalcID(p *Params) (map[wallet.BackendID]ID, error) {
id := make(map[wallet.BackendID]ID)
var err error
for i := range p.Parts[0] {
id[i], err = backend[i].CalcID(p)
if err != nil {
return nil, err
func CalcID(p *Params) (ID, error) {
var lastErr error
for _, b := range backend {
id, err := b.CalcID(p)
if err == nil {
return id, nil
}
lastErr = err
}
return id, nil

if lastErr != nil {
return ID{}, lastErr
}

return ID{}, errors.New("no valid ID found")
}

// Sign creates a signature from the account a on state s.
Expand Down
16 changes: 7 additions & 9 deletions channel/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,26 +17,24 @@ package channel
import (
"fmt"

"perun.network/go-perun/wallet"

"github.com/pkg/errors"
)

type (
// StateTransitionError happens in case of an invalid channel state transition.
StateTransitionError struct {
ID map[wallet.BackendID]ID
ID ID
}

// ActionError happens if an invalid action is applied to a channel state.
ActionError struct {
ID map[wallet.BackendID]ID
ID ID
}

// PhaseTransitionError happens in case of an invalid channel machine phase
// transition.
PhaseTransitionError struct {
ID map[wallet.BackendID]ID
ID ID
current Phase
PhaseTransition
}
Expand All @@ -58,20 +56,20 @@ func (e *PhaseTransitionError) Error() string {
}

// NewStateTransitionError creates a new StateTransitionError.
func NewStateTransitionError(id map[wallet.BackendID]ID, msg string) error {
func NewStateTransitionError(id ID, msg string) error {
return errors.Wrap(&StateTransitionError{
ID: id,
}, msg)
}

// NewActionError creates a new ActionError.
func NewActionError(id map[wallet.BackendID]ID, msg string) error {
func NewActionError(id ID, msg string) error {
return errors.Wrap(&ActionError{
ID: id,
}, msg)
}

func newPhaseTransitionError(id map[wallet.BackendID]ID, current Phase, expected PhaseTransition, msg string) error {
func newPhaseTransitionError(id ID, current Phase, expected PhaseTransition, msg string) error {
return errors.Wrap(&PhaseTransitionError{
ID: id,
current: current,
Expand All @@ -80,7 +78,7 @@ func newPhaseTransitionError(id map[wallet.BackendID]ID, current Phase, expected
}

func newPhaseTransitionErrorf(
id map[wallet.BackendID]ID,
id ID,
current Phase,
expected PhaseTransition,
format string,
Expand Down
10 changes: 4 additions & 6 deletions channel/errors_internal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,19 @@ import (
"errors"
"testing"

"perun.network/go-perun/wallet"

"github.com/stretchr/testify/assert"
)

func TestTransitionErrors(t *testing.T) {
assert.False(t, IsStateTransitionError(errors.New("No StateTransitionError")))
assert.True(t, IsStateTransitionError(NewStateTransitionError(map[wallet.BackendID]ID{TestBackendID: Zero}, "A StateTransitionError")))
assert.True(t, IsStateTransitionError(NewStateTransitionError(Zero, "A StateTransitionError")))

assert.False(t, IsActionError(errors.New("No ActionError")))
assert.True(t, IsActionError(NewActionError(map[wallet.BackendID]ID{TestBackendID: Zero}, "An ActionError")))
assert.True(t, IsActionError(NewActionError(Zero, "An ActionError")))

assert.False(t, IsPhaseTransitionError(errors.New("No PhaseTransitionError")))
assert.True(t, IsPhaseTransitionError(newPhaseTransitionError(
map[wallet.BackendID]ID{TestBackendID: Zero}, InitActing, PhaseTransition{InitActing, InitActing}, "A PhaseTransitionError")))
Zero, InitActing, PhaseTransition{InitActing, InitActing}, "A PhaseTransitionError")))
assert.True(t, IsPhaseTransitionError(newPhaseTransitionErrorf(
map[wallet.BackendID]ID{TestBackendID: Zero}, InitActing, PhaseTransition{InitActing, InitActing}, "A %s", "PhaseTransitionError")))
Zero, InitActing, PhaseTransition{InitActing, InitActing}, "A %s", "PhaseTransitionError")))
}
16 changes: 8 additions & 8 deletions channel/machine.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,12 @@ type (
// needed for persistence. The ID, Idx and Params only need to be persisted
// once per channel as they stay constant during a channel's lifetime.
Source interface {
ID() map[wallet.BackendID]ID // ID is the channel ID of this source. It is the same as Params().ID().
Idx() Index // Idx is the own index in the channel.
Params() *Params // Params are the channel parameters.
StagingTX() Transaction // StagingTX is the staged transaction (State+incomplete list of sigs).
CurrentTX() Transaction // CurrentTX is the current transaction (State+complete list of sigs).
Phase() Phase // Phase is the phase in which the channel is currently in.
ID() ID // ID is the channel ID of this source. It is the same as Params().ID().
Idx() Index // Idx is the own index in the channel.
Params() *Params // Params are the channel parameters.
StagingTX() Transaction // StagingTX is the staged transaction (State+incomplete list of sigs).
CurrentTX() Transaction // CurrentTX is the current transaction (State+complete list of sigs).
Phase() Phase // Phase is the phase in which the channel is currently in.
}
)

Expand Down Expand Up @@ -169,7 +169,7 @@ func restoreMachine(acc map[wallet.BackendID]wallet.Account, source Source) (*ma
}

// ID returns the channel id.
func (m *machine) ID() map[wallet.BackendID]ID {
func (m *machine) ID() ID {
return m.params.ID()
}

Expand Down Expand Up @@ -488,7 +488,7 @@ func (m *machine) expect(tr PhaseTransition) error {
// A StateMachine will additionally check the validity of the app-specific
// transition whereas an ActionMachine checks each Action as being valid.
func (m *machine) ValidTransition(to *State) error {
if !EqualIDs(to.ID, m.params.id) {
if to.ID != m.params.id {
return errors.New("new state's ID doesn't match")
}

Expand Down
6 changes: 2 additions & 4 deletions channel/mock_app.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ import (
"encoding/binary"
"fmt"

"perun.network/go-perun/wallet"

"github.com/pkg/errors"
)

Expand Down Expand Up @@ -170,9 +168,9 @@ func (a MockApp) execMockOp(op *MockOp) error {
case OpErr:
return errors.New("MockOp: runtime error")
case OpTransitionErr:
return NewStateTransitionError(map[wallet.BackendID]ID{}, "MockOp: state transition error")
return NewStateTransitionError(ID{}, "MockOp: state transition error")
case OpActionErr:
return NewActionError(map[wallet.BackendID]ID{}, "MockOp: action error")
return NewActionError(ID{}, "MockOp: action error")
case OpPanic:
panic("MockOp: panic")
case OpValid:
Expand Down
4 changes: 1 addition & 3 deletions channel/mock_app_internal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@ package channel
import (
"testing"

"perun.network/go-perun/wallet"

"github.com/stretchr/testify/assert"

wiretest "perun.network/go-perun/wire/test"
Expand Down Expand Up @@ -143,5 +141,5 @@ func MockActionAppTest(t *testing.T, app MockApp) {
}

func createState(op MockOp) *State {
return &State{ID: map[wallet.BackendID]ID{}, Version: 0, Allocation: Allocation{}, Data: NewMockOp(op), IsFinal: false}
return &State{ID: ID{}, Version: 0, Allocation: Allocation{}, Data: NewMockOp(op), IsFinal: false}
}
3 changes: 1 addition & 2 deletions channel/multi/subscription.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,10 @@ import (
"context"

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

// Subscribe creates a new multi-ledger AdjudicatorSubscription.
func (a *Adjudicator) Subscribe(ctx context.Context, chID map[wallet.BackendID]channel.ID) (channel.AdjudicatorSubscription, error) {
func (a *Adjudicator) Subscribe(ctx context.Context, chID channel.ID) (channel.AdjudicatorSubscription, error) {
asub := &AdjudicatorSubscription{
events: make(chan channel.AdjudicatorEvent),
errors: make(chan error),
Expand Down
Loading

0 comments on commit 7af28d5

Please sign in to comment.