From b1cfbb4ce6eafae65876eb7b39a26c47013e92fa Mon Sep 17 00:00:00 2001 From: Andrey Butusov Date: Fri, 14 Feb 2025 22:00:18 +0300 Subject: [PATCH] morph: fix error from `CalculateNonceAndVUB` The alphabetic key change event comes from the main chain with its hash, and when calculating vub, an error is returned because there is no hash in the FS chain. Ignore the error and calculate the value in another way. Signed-off-by: Andrey Butusov --- CHANGELOG.md | 1 + pkg/innerring/state.go | 4 ++-- pkg/morph/client/notary.go | 41 +++++++++++++++++++++++++++++++++----- 3 files changed, 39 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 11714be6e8..3d837a6c7c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,7 @@ Changelog for NeoFS Node - `neofs_node_engine_list_objects_time_bucket` metric (#3120) - The correct role parameter to invocation (#3127) - nil pointer error for `storage sanity` command (#3151) +- Calculation of VUB when it is impossible to get the transaction height (#3134) ### Changed - Number of cuncurrenly handled notifications from the chain was increased from 10 to 300 for IR (#3068) diff --git a/pkg/innerring/state.go b/pkg/innerring/state.go index abd5dfec7f..2a7412770f 100644 --- a/pkg/innerring/state.go +++ b/pkg/innerring/state.go @@ -126,9 +126,9 @@ func (s *Server) voteForFSChainValidator(validators keys.PublicKeys, trigger *ut ) if trigger != nil { - nonce, vub, err = s.morphClient.CalculateNonceAndVUB(*trigger) + nonce, vub, err = s.morphClient.CalculateNonceAndVUBWithFallback(*trigger) if err != nil { - return fmt.Errorf("could not calculate nonce and `validUntilBlock` values: %w", err) + return err } vubP = &vub } diff --git a/pkg/morph/client/notary.go b/pkg/morph/client/notary.go index 27d0a051d1..73fe02ed14 100644 --- a/pkg/morph/client/notary.go +++ b/pkg/morph/client/notary.go @@ -65,6 +65,8 @@ const ( ) var errUnexpectedItems = errors.New("invalid number of NEO VM arguments on stack") +var errNoTxHeight = errors.New("could not get transaction height") +var errNonceVubCalculation = errors.New("could not calculate nonce and validUntilBlock values") func defaultNotaryConfig(c *Client) *notaryCfg { return ¬aryCfg{ @@ -266,9 +268,9 @@ func (c *Client) UpdateNotaryList(notaries keys.PublicKeys, txHash util.Uint256) panic(notaryNotEnabledPanicMsg) } - nonce, vub, err := c.CalculateNonceAndVUB(txHash) + nonce, vub, err := c.CalculateNonceAndVUBWithFallback(txHash) if err != nil { - return fmt.Errorf("could not calculate nonce and `valicUntilBlock` values: %w", err) + return err } return c.notaryInvokeAsCommittee( @@ -290,9 +292,9 @@ func (c *Client) UpdateNeoFSAlphabetList(alphas keys.PublicKeys, txHash util.Uin panic(notaryNotEnabledPanicMsg) } - nonce, vub, err := c.CalculateNonceAndVUB(txHash) + nonce, vub, err := c.CalculateNonceAndVUBWithFallback(txHash) if err != nil { - return fmt.Errorf("could not calculate nonce and `valicUntilBlock` values: %w", err) + return err } return c.notaryInvokeAsCommittee( @@ -767,9 +769,17 @@ func (c *Client) CalculateNonceAndVUB(hash util.Uint256) (nonce uint32, vub uint nonce = binary.LittleEndian.Uint32(hash.BytesLE()) + if hash.Equals(util.Uint256{}) { + c.logger.Debug("get zero hash to calculate nonce and vub") + vub, err = c.notaryTxValidationLimit(conn) + if err != nil { + return 0, 0, fmt.Errorf("could not get vub validation limit: %w", err) + } + return nonce, vub, nil + } height, err := c.getTransactionHeight(conn, hash) if err != nil { - return 0, 0, fmt.Errorf("could not get transaction height: %w", err) + return 0, 0, fmt.Errorf("%w: %w", errNoTxHeight, err) } return nonce, height + c.notary.txValidTime, nil @@ -786,3 +796,24 @@ func (c *Client) getTransactionHeight(conn *connection, h util.Uint256) (uint32, c.cache.txHeights.Add(h, height) return height, nil } + +// CalculateNonceAndVUB calculates nonce and ValidUntilBlock values +// based on transaction hash, and if it cannot get transaction height, +// then it calculates alternatively rounded. +func (c *Client) CalculateNonceAndVUBWithFallback(hash util.Uint256) (nonce uint32, vub uint32, err error) { + nonce, vub, err = c.CalculateNonceAndVUB(hash) + if err != nil { + if !errors.Is(err, errNoTxHeight) { + return 0, 0, fmt.Errorf("%w: %w", errNonceVubCalculation, err) + } + + c.logger.Debug(errNonceVubCalculation.Error(), zap.Error(err), zap.Stringer("hash", hash)) + var err2 error + nonce, vub, err2 = c.CalculateNonceAndVUB(util.Uint256{}) + if err2 != nil { + return 0, 0, fmt.Errorf("%w for %s: %w. And for zero hash: %w", errNonceVubCalculation, hash.String(), err, err2) + } + } + + return nonce, vub, nil +}