-
Notifications
You must be signed in to change notification settings - Fork 9
sdk/state: refactor validations to check against the channel state #270
Changes from 1 commit
105eed0
f04f586
7da38ad
809433e
4c1636a
860dcf7
bcd9fc4
3e69491
9fd645b
1a33b01
b1e52be
687c88a
9665200
27032bb
25bb784
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -192,9 +192,14 @@ func (c *Channel) OpenTx() (formationTx *txnbuild.Transaction, err error) { | |
// initiating the channel. | ||
func (c *Channel) ProposeOpen(p OpenParams) (OpenAgreement, error) { | ||
// if the channel is already open, error. | ||
if c.openAgreement.isFull() { | ||
return OpenAgreement{}, fmt.Errorf("cannot propose a new open if channel is already opened") | ||
cs, err := c.State() | ||
if err != nil { | ||
return OpenAgreement{}, fmt.Errorf("getting channel state: %w", err) | ||
} | ||
if cs >= StateOpen { | ||
return OpenAgreement{}, fmt.Errorf("cannot propose a new open if channel has already opened") | ||
} | ||
|
||
c.startingSequence = c.initiatorEscrowAccount().SequenceNumber + 1 | ||
|
||
d := OpenAgreementDetails{ | ||
|
@@ -224,7 +229,11 @@ func (c *Channel) ProposeOpen(p OpenParams) (OpenAgreement, error) { | |
|
||
func (c *Channel) validateOpen(m OpenAgreement) error { | ||
// if the channel is already open, error. | ||
if c.openAgreement.isFull() { | ||
cs, err := c.State() | ||
if err != nil { | ||
return fmt.Errorf("getting channel state: %w", err) | ||
} | ||
if cs >= StateOpen { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this is better than There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
❗ I think there could be cases where |
||
return fmt.Errorf("cannot confirm a new open if channel is already opened") | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -96,7 +96,11 @@ func (c *Channel) ProposePayment(amount int64) (CloseAgreement, error) { | |
} | ||
|
||
// If the channel is not open yet, error. | ||
if c.latestAuthorizedCloseAgreement.isEmpty() { | ||
cs, err := c.State() | ||
if err != nil { | ||
return CloseAgreement{}, fmt.Errorf("getting channel state: %w", err) | ||
} | ||
if cs < StateOpen { | ||
acharb marked this conversation as resolved.
Show resolved
Hide resolved
|
||
return CloseAgreement{}, fmt.Errorf("cannot propose a payment before channel is opened") | ||
} | ||
|
||
|
@@ -158,7 +162,11 @@ var ErrUnderfunded = fmt.Errorf("account is underfunded to make payment") | |
// on the state of the close agreement signatures. | ||
func (c *Channel) validatePayment(ca CloseAgreement) (err error) { | ||
// If the channel is not open yet, error. | ||
if c.latestAuthorizedCloseAgreement.isEmpty() { | ||
cs, err := c.State() | ||
if err != nil { | ||
return fmt.Errorf("getting channel state: %w", err) | ||
} | ||
if cs < StateOpen { | ||
Comment on lines
-161
to
+169
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍🏻 I think using the state here is good, however I think the condition needs to be |
||
return fmt.Errorf("cannot confirm a payment before channel is opened") | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
❗ I think we're missing catching
StateFailed
?StateFailed
is< StateOpen
so will not be caught here and so the open will be allowed. I think we should err on the side of allowing only valid scenarios, so:🤔 Similar to my other two comments above I think this changes the condition to be a little more disconnected from the needs of the function. In this case the function is protecting against replacing an
c.openAgreement
that already exists. We're replacing that protective guard with one about the state, that indirectly protects against replacing the openAgreement.❗ Note that there's actually a bug in this function in the original code. The original condition should have been
!c.openAgreement.isEmpty()
because we should never allow proposing two opens because that could result in us losing control of the channel. If we make that fix I don't think we can reproduce that condition with the state check anymore, because the state would beStateNone
, so I'm thinking we need to keep the open agreement condition instead, or maybe 💡 we need more states, such asStateOpenProposed
,StateOpenConfirmed
. That might not be a bad idea.For example:
StateFailed
StateOpenProposed
= only one signer on the openStateOpenConfirmed
= two signers, not ingestedStateOpened
= ingested, actually opened on networkStateClosing
StateClosed
❓ Wdyt about keeping the original condition and adding the state condition with new states? The original condition is defensive to make sure we don't replace data we need, or that data exists before we use it. The state condition is more informative.