[#787] morph: Return VUB for IR service calls

Signed-off-by: Dmitrii Stepanov <d.stepanov@yadro.com>
This commit is contained in:
Dmitrii Stepanov 2023-11-08 12:05:03 +03:00
parent 518f3baf41
commit 2393d13e4d
12 changed files with 78 additions and 41 deletions

View file

@ -26,7 +26,8 @@ func Delete(c *Client, witness core.RemovalWitness) error {
prm.SetToken(tok.Marshal())
}
return c.Delete(prm)
_, err := c.Delete(prm)
return err
}
// DeletePrm groups parameters of Delete client operation.
@ -62,13 +63,13 @@ func (d *DeletePrm) SetKey(key []byte) {
// Delete removes the container from FrostFS system
// through Container contract call.
//
// Returns any error encountered that caused
// Returns valid until block and any error encountered that caused
// the removal to interrupt.
//
// If TryNotary is provided, calls notary contract.
func (c *Client) Delete(p DeletePrm) error {
func (c *Client) Delete(p DeletePrm) (uint32, error) {
if len(p.signature) == 0 && !p.IsControl() {
return errNilArgument
return 0, errNilArgument
}
prm := client.InvokePrm{}
@ -76,9 +77,9 @@ func (c *Client) Delete(p DeletePrm) error {
prm.SetArgs(p.cnr, p.signature, p.key, p.token)
prm.InvokePrmOptional = p.InvokePrmOptional
_, err := c.client.Invoke(prm)
res, err := c.client.Invoke(prm)
if err != nil {
return fmt.Errorf("could not invoke method (%s): %w", deleteMethod, err)
return 0, fmt.Errorf("could not invoke method (%s): %w", deleteMethod, err)
}
return nil
return res.VUB, nil
}

View file

@ -11,14 +11,17 @@ import (
// If `force` is true, this call is normally initiated by a control
// service command and uses a control notary transaction internally
// to ensure all nodes produce the same transaction with high probability.
func (c *Client) NewEpoch(epoch uint64, force bool) error {
// If vub > 0, vub will be used as valid until block value.
func (c *Client) NewEpoch(epoch uint64, vub uint32, force bool) (uint32, error) {
prm := client.InvokePrm{}
prm.SetMethod(newEpochMethod)
prm.SetArgs(epoch)
prm.SetControlTX(force)
prm.SetVUB(vub)
if _, err := c.client.Invoke(prm); err != nil {
return fmt.Errorf("could not invoke method (%s): %w", newEpochMethod, err)
res, err := c.client.Invoke(prm)
if err != nil {
return 0, fmt.Errorf("could not invoke method (%s): %w", newEpochMethod, err)
}
return nil
return res.VUB, nil
}

View file

@ -43,17 +43,20 @@ func (c *Client) AddPeer(p AddPeerPrm) error {
}
// ForceRemovePeer marks the given peer as offline via a notary control transaction.
func (c *Client) ForceRemovePeer(nodeInfo netmap.NodeInfo) error {
// If vub > 0, vub will be used as valid until block value.
func (c *Client) ForceRemovePeer(nodeInfo netmap.NodeInfo, vub uint32) (uint32, error) {
if !c.client.WithNotary() {
return fmt.Errorf("peer can be forcefully removed only in notary environment")
return 0, fmt.Errorf("peer can be forcefully removed only in notary environment")
}
prm := UpdatePeerPrm{}
prm.SetKey(nodeInfo.PublicKey())
prm.SetControlTX(true)
prm.SetVUB(vub)
if err := c.UpdatePeerState(prm); err != nil {
return fmt.Errorf("updating peer state: %v", err)
vub, err := c.UpdatePeerState(prm)
if err != nil {
return 0, fmt.Errorf("updating peer state: %v", err)
}
return nil
return vub, nil
}

View file

@ -36,7 +36,7 @@ func (u *UpdatePeerPrm) SetMaintenance() {
}
// UpdatePeerState changes peer status through Netmap contract call.
func (c *Client) UpdatePeerState(p UpdatePeerPrm) error {
func (c *Client) UpdatePeerState(p UpdatePeerPrm) (uint32, error) {
method := updateStateMethod
if c.client.WithNotary() && c.client.IsAlpha() {
@ -55,8 +55,9 @@ func (c *Client) UpdatePeerState(p UpdatePeerPrm) error {
prm.SetArgs(int64(p.state), p.key)
prm.InvokePrmOptional = p.InvokePrmOptional
if _, err := c.client.Invoke(prm); err != nil {
return fmt.Errorf("could not invoke smart contract: %w", err)
res, err := c.client.Invoke(prm)
if err != nil {
return 0, fmt.Errorf("could not invoke smart contract: %w", err)
}
return nil
return res.VUB, nil
}

View file

@ -378,7 +378,7 @@ func (c *Client) NotaryInvoke(contract util.Uint160, fee fixedn.Fixed8, nonce ui
// not expected to be signed by the current node.
//
// Considered to be used by non-IR nodes.
func (c *Client) NotaryInvokeNotAlpha(contract util.Uint160, fee fixedn.Fixed8, method string, args ...any) (uint32, error) {
func (c *Client) NotaryInvokeNotAlpha(contract util.Uint160, fee fixedn.Fixed8, vubP *uint32, method string, args ...any) (uint32, error) {
c.switchLock.RLock()
defer c.switchLock.RUnlock()
@ -390,7 +390,7 @@ func (c *Client) NotaryInvokeNotAlpha(contract util.Uint160, fee fixedn.Fixed8,
return c.Invoke(contract, fee, method, args...)
}
return c.notaryInvoke(false, false, contract, rand.Uint32(), nil, method, args...)
return c.notaryInvoke(false, false, contract, rand.Uint32(), vubP, method, args...)
}
// NotarySignAndInvokeTX signs and sends notary request that was received from

View file

@ -100,6 +100,8 @@ type InvokePrmOptional struct {
// It's only used by notary transactions and it affects only the
// computation of `validUntilBlock` values.
controlTX bool
// vub is used to set custom valid until block value.
vub uint32
}
// SetHash sets optional hash of the transaction.
@ -120,6 +122,11 @@ func (i *InvokePrmOptional) IsControl() bool {
return i.controlTX
}
// SetVUB sets valid until block value.
func (i *InvokePrmOptional) SetVUB(v uint32) {
i.vub = v
}
type InvokeRes struct {
VUB uint32
}
@ -136,11 +143,11 @@ type InvokeRes struct {
func (s StaticClient) Invoke(prm InvokePrm) (InvokeRes, error) {
var res InvokeRes
var err error
var vubP *uint32
if s.tryNotary {
if s.alpha {
var (
nonce uint32 = 1
vubP *uint32
vub uint32
err error
)
@ -158,11 +165,19 @@ func (s StaticClient) Invoke(prm InvokePrm) (InvokeRes, error) {
vubP = &vub
}
if prm.vub > 0 {
vubP = &prm.vub
}
res.VUB, err = s.client.NotaryInvoke(s.scScriptHash, s.fee, nonce, vubP, prm.method, prm.args...)
return res, err
}
res.VUB, err = s.client.NotaryInvokeNotAlpha(s.scScriptHash, s.fee, prm.method, prm.args...)
if prm.vub > 0 {
vubP = &prm.vub
}
res.VUB, err = s.client.NotaryInvokeNotAlpha(s.scScriptHash, s.fee, vubP, prm.method, prm.args...)
return res, err
}