-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: Update wait interface, Add FetchStakingOperation and ReloadStakingOperation #37
Changes from all commits
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 |
---|---|---|
|
@@ -193,7 +193,7 @@ func (s *StakingOperation) GetSignedVoluntaryExitMessages() ([]string, error) { | |
return signedVoluntaryExitMessages, nil | ||
} | ||
|
||
func (c *Client) Wait(ctx context.Context, stakingOperation *StakingOperation, o ...WaitOption) (*StakingOperation, error) { | ||
func (c *Client) Wait(ctx context.Context, stakingOperation *StakingOperation, o ...WaitOption) error { | ||
options := &waitOptions{ | ||
intervalSeconds: 5, | ||
timeoutSeconds: 3600, | ||
|
@@ -206,50 +206,60 @@ func (c *Client) Wait(ctx context.Context, stakingOperation *StakingOperation, o | |
startTime := time.Now() | ||
|
||
for time.Since(startTime).Seconds() < float64(options.timeoutSeconds) { | ||
so, err := c.fetchExternalStakingOperation(ctx, stakingOperation) | ||
if err != nil { | ||
return stakingOperation, err | ||
if err := c.ReloadStakingOperation(ctx, stakingOperation); err != nil { | ||
return err | ||
} | ||
stakingOperation = so | ||
|
||
if stakingOperation.isTerminalState() { | ||
return stakingOperation, nil | ||
return nil | ||
} | ||
|
||
if time.Since(startTime).Seconds() > float64(options.timeoutSeconds) { | ||
return stakingOperation, fmt.Errorf("staking operation timed out") | ||
return fmt.Errorf("staking operation timed out") | ||
} | ||
|
||
time.Sleep(time.Duration(options.intervalSeconds) * time.Second) | ||
} | ||
|
||
return stakingOperation, fmt.Errorf("staking operation timed out") | ||
return fmt.Errorf("staking operation timed out") | ||
} | ||
|
||
// FetchExternalStakingOperation reloads a staking operation from the API associated | ||
// with an address. | ||
func (c *Client) fetchExternalStakingOperation(ctx context.Context, stakingOperation *StakingOperation) (*StakingOperation, error) { | ||
// ReloadStakingOperation reloads a staking operation from the backend with the latest state. | ||
// It ensures only newly constructed transactions are added to the staking operation and any existing transactions are untouched. | ||
func (c *Client) ReloadStakingOperation(ctx context.Context, stakingOperation *StakingOperation) error { | ||
so, httpResp, err := c.client.StakeAPI.GetExternalStakingOperation( | ||
ctx, | ||
stakingOperation.NetworkID(), | ||
stakingOperation.AddressID(), | ||
stakingOperation.ID(), | ||
).Execute() | ||
if err != nil { | ||
return nil, errors.MapToUserFacing(err, httpResp) | ||
return errors.MapToUserFacing(err, httpResp) | ||
} | ||
|
||
stakingOperation.model = so | ||
|
||
for _, tx := range so.Transactions { | ||
if !stakingOperation.hasTransactionByUnsignedPayload(tx.UnsignedPayload) { | ||
newTx, err := newTransactionFromModel(&tx) | ||
if err != nil { | ||
return nil, err | ||
return err | ||
} | ||
|
||
stakingOperation.transactions = append(stakingOperation.transactions, newTx) | ||
} | ||
} | ||
return stakingOperation, nil | ||
return nil | ||
} | ||
|
||
// FetchStakingOperation fetches a staking operation from the backend given a networkID, addressID, and stakingOperationID. | ||
func (c *Client) FetchStakingOperation(ctx context.Context, networkID, addressID, stakingOperationID string) (*StakingOperation, error) { | ||
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. Is this the same name we use in other SDKs? I thought we included the word external for some reason? (since you can fetch a wallet based op that is slightly different?) 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. Yes. In both node and ruby we seem to call it just Since Go SDK is purely external address based for now, I decided not to introduce the wallet id param and simply call |
||
so, httpResp, err := c.client.StakeAPI.GetExternalStakingOperation(ctx, networkID, addressID, stakingOperationID).Execute() | ||
if err != nil { | ||
return nil, errors.MapToUserFacing(err, httpResp) | ||
} | ||
|
||
return newStakingOperationFromModel(so) | ||
} | ||
|
||
func (s *StakingOperation) hasTransactionByUnsignedPayload(unsignedPayload string) bool { | ||
|
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.
Im okay with this change, but curious as to why?
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.
The
Wait
interface attempts to relieve control back to user when the staking operation has terminated along with an up-to-date staking operation object. The options are b/w returning back an updated object vs doing in-place.Since we pass the staking operation by reference it's possible to do an in-place update. Returning back an explicit staking operation object in response didn't feel the right thing to do. Made it slightly more verbose that what I had imagined it to be.
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.
It feels like
Wait()
should be a method on theStakingOperation
struct in this case.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.
^ Ideally yes - but in the Go SDK all operations are mostly performed directly on the client directly. Doing on wait on staking operation would require access to the client to make backend calls but the SDK is not setup for that (I believe that is intentional)
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.
This is the "Go" way since the actions are happening on the API (ie Client) not on the structs. Structs have functions for local changes, client has remote change mutations.