Skip to content

Commit f3f8a24

Browse files
author
Manoranjith
authored
Merge pull request #306 from perun-network/155-revise-channel
💥 Channel.Update/ForceUpdate: updater no longer returns error Relates to #155
2 parents ba076a9 + 90d0136 commit f3f8a24

File tree

8 files changed

+36
-35
lines changed

8 files changed

+36
-35
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ func main() {
146146
}()
147147

148148
// send a channel update request to the other channel peer(s)
149-
err = ch.Update(ctx, func(s *channel.State) error {
149+
err = ch.Update(ctx, func(s *channel.State) {
150150
// update state s, e.g., moving funds or changing app data
151151
})
152152
if err != nil { /* handle error */ }

channel/machine.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -475,15 +475,15 @@ func (m *machine) expect(tr PhaseTransition) error {
475475
return nil
476476
}
477477

478-
// validTransition checks that the transition from the current to the provided
478+
// ValidTransition checks that the transition from the current to the provided
479479
// state is valid. The following checks are run:
480480
// * matching channel ids
481481
// * no transition from final state
482482
// * version increase by 1
483483
// * preservation of balances
484484
// A StateMachine will additionally check the validity of the app-specific
485485
// transition whereas an ActionMachine checks each Action as being valid.
486-
func (m *machine) validTransition(to *State) error {
486+
func (m *machine) ValidTransition(to *State) error {
487487
if to.ID != m.params.id {
488488
return errors.New("new state's ID doesn't match")
489489
}

channel/statemachine.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ func (m *StateMachine) validTransition(to *State, actor Index) (err error) {
134134
if actor >= m.N() {
135135
return errors.New("actor index is out of range")
136136
}
137-
if err := m.machine.validTransition(to); err != nil {
137+
if err := m.machine.ValidTransition(to); err != nil {
138138
return err
139139
}
140140

client/adjudicate.go

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -178,16 +178,19 @@ func (c *Channel) registerDispute(ctx context.Context) error {
178178
return nil
179179
}
180180

181-
// ForceUpdate enforces a channel update on the adjudicator. `update` gets as
182-
// input a copy of the current state and is expected to modify the state as
183-
// intended. It should not to increment the version number as this is
184-
// automatically.
181+
// ForceUpdate enforces a state update through the adjudicator as specified by
182+
// the `updater` function.
183+
//
184+
// The updater function must adhere to the following rules:
185+
// - The version must not be changed. It is incremented automatically.
186+
// - The assets must not be changed.
187+
// - The locked allocation must not be changed.
185188
//
186189
// Returns TxTimedoutError when the program times out waiting for a transaction
187190
// to be mined. Returns ChainNotReachableError if the connection to the
188191
// blockchain network fails when sending a transaction to / reading from the
189192
// blockchain.
190-
func (c *Channel) ForceUpdate(ctx context.Context, update func(*channel.State) error) error {
193+
func (c *Channel) ForceUpdate(ctx context.Context, updater func(*channel.State)) error {
191194
err := c.ensureRegistered(ctx)
192195
if err != nil {
193196
return err
@@ -204,10 +207,12 @@ func (c *Channel) ForceUpdate(ctx context.Context, update func(*channel.State) e
204207

205208
// Update state
206209
state := ar.Tx.State.Clone()
210+
updater(state)
207211
state.Version++
208-
err = update(state)
209-
if err != nil {
210-
return errors.WithMessage(err, "updating state")
212+
213+
// Check state transition.
214+
if err := c.machine.ValidTransition(state); err != nil {
215+
return errors.WithMessage(err, "validating state transition")
211216
}
212217

213218
// Apply state in machine and generate signature

client/test/channel.go

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -98,21 +98,20 @@ func (ch *paymentChannel) acceptSubchannel(
9898
return subchannel
9999
}
100100

101-
func (ch *paymentChannel) sendUpdate(update func(*channel.State) error, desc string) {
101+
func (ch *paymentChannel) sendUpdate(updater func(*channel.State), desc string) {
102102
ch.log.Debugf("Sending update: %s", desc)
103103
ctx, cancel := context.WithTimeout(context.Background(), ch.r.timeout)
104104
defer cancel()
105105

106-
err := ch.Update(ctx, update)
106+
err := ch.Update(ctx, updater)
107107
ch.log.Infof("Sent update: %s, err: %v", desc, err)
108108
assert.NoError(ch.r.t, err)
109109
}
110110

111111
func (ch *paymentChannel) sendTransfer(amount channel.Bal, desc string) {
112112
ch.sendUpdate(
113-
func(state *channel.State) error {
113+
func(state *channel.State) {
114114
transferBal(stateBals(state), ch.Idx(), amount)
115-
return nil
116115
},
117116
desc,
118117
)
@@ -157,9 +156,8 @@ func (ch *paymentChannel) assertBals(state *channel.State) {
157156
}
158157

159158
func (ch *paymentChannel) sendFinal() {
160-
ch.sendUpdate(func(state *channel.State) error {
159+
ch.sendUpdate(func(state *channel.State) {
161160
state.IsFinal = true
162-
return nil
163161
}, "final")
164162
assert.True(ch.r.t, ch.State().IsFinal)
165163
}

client/test/progression.go

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -95,14 +95,13 @@ func (r *Paul) exec(_cfg ExecConfig, ch *paymentChannel) {
9595
r.waitStage() // wait for setup complete
9696

9797
// progress
98-
assert.NoError(ch.ForceUpdate(ctx, func(s *channel.State) error {
98+
assert.NoError(ch.ForceUpdate(ctx, func(s *channel.State) {
9999
bal := func(user channel.Index) int64 {
100100
return s.Balances[assetIdx][user].Int64()
101101
}
102102
half := (bal(0) + bal(1)) / 2 //nolint:gomnd
103103
s.Balances[assetIdx][0] = big.NewInt(half)
104104
s.Balances[assetIdx][1] = big.NewInt(half)
105-
return nil
106105
}))
107106

108107
// await our progression confirmation
@@ -167,14 +166,13 @@ func (r *Paula) exec(_cfg ExecConfig, ch *paymentChannel, _ *acceptNextPropHandl
167166
r.t.Logf("%v received progression confirmation 1", r.setup.Name)
168167

169168
// we progress
170-
assert.NoError(ch.ForceUpdate(ctx, func(s *channel.State) error {
169+
assert.NoError(ch.ForceUpdate(ctx, func(s *channel.State) {
171170
bal := func(user channel.Index) int64 {
172171
return s.Balances[assetIdx][user].Int64()
173172
}
174173
half := (bal(0) + bal(1)) / 2 //nolint:gomnd
175174
s.Balances[assetIdx][0] = big.NewInt(half + paulPaulaBalTransferAmount)
176175
s.Balances[assetIdx][1] = big.NewInt(half - paulPaulaBalTransferAmount)
177-
return nil
178176
}))
179177

180178
// await our progression confirmation

client/update.go

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -131,14 +131,18 @@ func (r *UpdateResponder) Reject(ctx context.Context, reason string) error {
131131
return r.channel.handleUpdateRej(ctx, r.pidx, r.req, reason)
132132
}
133133

134-
// Update updates the channel state using the update function and proposes the
135-
// new state to all other channel participants. The update function must not
136-
// update the version counter.
134+
// Update proposes a state update to the channel participants as
135+
// specified by the `updater` function.
136+
//
137+
// The updater function must adhere to the following rules:
138+
// - The version must not be changed. It is incremented automatically.
139+
// - The assets must not be changed.
140+
// - The locked allocation must not be changed.
137141
//
138142
// Returns nil if all peers accept the update. Returns RequestTimedOutError if
139143
// any peer did not respond before the context expires or is cancelled. Returns
140144
// an error if any runtime error occurs or any peer rejects the update.
141-
func (c *Channel) Update(ctx context.Context, update func(*channel.State) error) (err error) {
145+
func (c *Channel) Update(ctx context.Context, updater func(*channel.State)) error {
142146
if ctx == nil {
143147
return errors.New("context must not be nil")
144148
}
@@ -152,9 +156,7 @@ func (c *Channel) Update(ctx context.Context, update func(*channel.State) error)
152156
return c.update(ctx,
153157
func(state *channel.State) error {
154158
// apply update
155-
if err := update(state); err != nil {
156-
return err
157-
}
159+
updater(state)
158160

159161
// validate
160162
return c.validTwoPartyUpdateState(state)
@@ -239,9 +241,9 @@ func (c *Channel) checkUpdateError(ctx context.Context, updateErr error) {
239241
}
240242
}
241243

242-
func (c *Channel) update(ctx context.Context, update func(*channel.State) error) (err error) {
244+
func (c *Channel) update(ctx context.Context, updater func(*channel.State) error) (err error) {
243245
state := c.machine.State().Clone()
244-
if err := update(state); err != nil {
246+
if err := updater(state); err != nil {
245247
return err
246248
}
247249
state.Version++

client/virtual_channel_test.go

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -268,15 +268,13 @@ func setupVirtualChannelTest(t *testing.T, ctx context.Context) (vct virtualChan
268268
t.Fatalf("Error in go-routine: %v", err)
269269
}
270270

271-
err = vct.chAliceBob.Update(ctx, func(s *channel.State) error {
271+
err = vct.chAliceBob.Update(ctx, func(s *channel.State) {
272272
s.Balances = channel.Balances{vct.virtualBalsUpdated}
273-
return nil
274273
})
275274
require.NoError(err, "updating virtual channel")
276275

277-
err = vct.chAliceBob.Update(ctx, func(s *channel.State) error {
276+
err = vct.chAliceBob.Update(ctx, func(s *channel.State) {
278277
s.IsFinal = true
279-
return nil
280278
})
281279
require.NoError(err, "updating virtual channel")
282280
return vct

0 commit comments

Comments
 (0)