Skip to content
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

Removed reusing error variables in 'stateManager'. #1501

Merged
merged 6 commits into from
Sep 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions pkg/state/appender.go
Original file line number Diff line number Diff line change
Expand Up @@ -836,8 +836,9 @@ func (a *txAppender) appendBlock(params *appendBlockParams) error {
}
// check whether the calculated snapshot state hash equals with the provided one
if blockStateHash, present := params.block.GetStateHash(); present && blockStateHash != stateHash {
return errors.Wrapf(errBlockSnapshotStateHashMismatch, "state hash mismatch; provided '%s', caluclated '%s'",
blockStateHash.String(), stateHash.String(),
return errors.Wrapf(errBlockSnapshotStateHashMismatch,
"block %d state hash mismatch — provided '%s', caluclated '%s'",
currentBlockHeight, blockStateHash.String(), stateHash.String(),
)
}

Expand Down
204 changes: 121 additions & 83 deletions pkg/state/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package state
import (
"bytes"
"context"
stderrs "errors"
"fmt"
"io/fs"
"math/big"
Expand Down Expand Up @@ -481,9 +482,9 @@ func initGenesis(state *stateManager, height uint64, settings *settings.Blockcha
if err != nil {
return errors.Wrap(err, "failed to get genesis block from state")
}
err = settings.Genesis.GenerateBlockID(settings.AddressSchemeCharacter)
if err != nil {
return errors.Wrap(err, "failed to generate genesis block id from config")

if genErr := settings.Genesis.GenerateBlockID(settings.AddressSchemeCharacter); genErr != nil {
return errors.Wrap(genErr, "failed to generate genesis block id from config")
}
if !bytes.Equal(genesis.ID.Bytes(), settings.Genesis.ID.Bytes()) {
return errors.New("genesis blocks from state and config mismatch")
Expand Down Expand Up @@ -946,9 +947,9 @@ func (s *stateManager) newestAssetBalance(addr proto.AddressID, asset proto.Asse
// Something weird happened.
return 0, err
}
balance, err = diff.applyToAssetBalance(balance)
if err != nil {
return 0, errors.Errorf("given account has negative balance at this point: %v", err)
balance, aErr := diff.applyToAssetBalance(balance)
if aErr != nil {
return 0, errors.Errorf("given account has negative balance at this point: %v", aErr)
}
return balance, nil
}
Expand Down Expand Up @@ -1332,8 +1333,10 @@ func (s *stateManager) AddBlock(block []byte) (*proto.Block, error) {
s.newBlocks.setNewBinary([][]byte{block})
rs, err := s.addBlocks()
if err != nil {
if err := s.rw.syncWithDb(); err != nil {
zap.S().Fatalf("Failed to add blocks and can not sync block storage with the database after failure: %v", err)
if syncErr := s.rw.syncWithDb(); syncErr != nil {
zap.S().Fatalf("Failed to add blocks and can not sync block storage with the database after failure: %v",
stderrs.Join(err, syncErr),
)
}
return nil, err
}
Expand All @@ -1344,8 +1347,10 @@ func (s *stateManager) AddDeserializedBlock(block *proto.Block) (*proto.Block, e
s.newBlocks.setNew([]*proto.Block{block})
rs, err := s.addBlocks()
if err != nil {
if err := s.rw.syncWithDb(); err != nil {
zap.S().Fatalf("Failed to add blocks and can not sync block storage with the database after failure: %v", err)
if syncErr := s.rw.syncWithDb(); syncErr != nil {
zap.S().Fatalf("Failed to add blocks and can not sync block storage with the database after failure: %v",
stderrs.Join(err, syncErr),
)
}
return nil, err
}
Expand All @@ -1355,8 +1360,10 @@ func (s *stateManager) AddDeserializedBlock(block *proto.Block) (*proto.Block, e
func (s *stateManager) AddBlocks(blockBytes [][]byte) error {
s.newBlocks.setNewBinary(blockBytes)
if _, err := s.addBlocks(); err != nil {
if err := s.rw.syncWithDb(); err != nil {
zap.S().Fatalf("Failed to add blocks and can not sync block storage with the database after failure: %v", err)
if syncErr := s.rw.syncWithDb(); syncErr != nil {
zap.S().Fatalf("Failed to add blocks and can not sync block storage with the database after failure: %v",
stderrs.Join(err, syncErr),
)
}
return err
}
Expand All @@ -1368,8 +1375,10 @@ func (s *stateManager) AddBlocksWithSnapshots(blockBytes [][]byte, snapshots []*
return errors.Wrap(err, "failed to set new blocks with snapshots")
}
if _, err := s.addBlocks(); err != nil {
if snErr := s.rw.syncWithDb(); snErr != nil {
zap.S().Fatalf("Failed to add blocks and can not sync block storage with the database after failure: %v", snErr)
if syncErr := s.rw.syncWithDb(); syncErr != nil {
zap.S().Fatalf("Failed to add blocks and can not sync block storage with the database after failure: %v",
stderrs.Join(err, syncErr),
)
}
return err
}
Expand All @@ -1382,8 +1391,10 @@ func (s *stateManager) AddDeserializedBlocks(
s.newBlocks.setNew(blocks)
lastBlock, err := s.addBlocks()
if err != nil {
if err = s.rw.syncWithDb(); err != nil {
zap.S().Fatalf("Failed to add blocks and can not sync block storage with the database after failure: %v", err)
if syncErr := s.rw.syncWithDb(); syncErr != nil {
zap.S().Fatalf("Failed to add blocks and can not sync block storage with the database after failure: %v",
stderrs.Join(err, syncErr),
)
}
return nil, err
}
Expand All @@ -1399,8 +1410,10 @@ func (s *stateManager) AddDeserializedBlocksWithSnapshots(
}
lastBlock, err := s.addBlocks()
if err != nil {
if err := s.rw.syncWithDb(); err != nil {
zap.S().Fatalf("Failed to add blocks and can not sync block storage with the database after failure: %v", err)
if syncErr := s.rw.syncWithDb(); syncErr != nil {
zap.S().Fatalf("Failed to add blocks and can not sync block storage with the database after failure: %v",
stderrs.Join(err, syncErr),
)
}
return nil, err
}
Expand Down Expand Up @@ -1613,8 +1626,8 @@ func (s *stateManager) blockchainHeightAction(blockchainHeight uint64, lastBlock
return err
}
if termIsOver {
if err = s.updateBlockReward(lastBlock, blockchainHeight); err != nil {
return err
if ubrErr := s.updateBlockReward(lastBlock, blockchainHeight); ubrErr != nil {
return ubrErr
}
}
return nil
Expand Down Expand Up @@ -1774,14 +1787,14 @@ func (s *stateManager) recalculateVotesAfterCappedRewardActivationInVotingPeriod
return nil
}

func (s *stateManager) addBlocks() (*proto.Block, error) {
func (s *stateManager) addBlocks() (_ *proto.Block, retErr error) { //nolint:nonamedreturns // needs in defer
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
defer func() {
// Reset in-memory storages and load last block in defer.
s.reset()
if err := s.loadLastBlock(); err != nil {
zap.S().Fatalf("Failed to load last block: %v", err)
if lbErr := s.loadLastBlock(); lbErr != nil {
zap.S().Fatalf("Failed to load last block: %v", stderrs.Join(retErr, lbErr))
}
s.newBlocks.reset()
}()
Expand All @@ -1792,14 +1805,14 @@ func (s *stateManager) addBlocks() (*proto.Block, error) {
}

// Read some useful values for later.
lastAppliedBlock, err := s.topBlock()
if err != nil {
return nil, wrapErr(RetrievalError, err)
lastAppliedBlock, tbErr := s.topBlock()
if tbErr != nil {
return nil, wrapErr(RetrievalError, tbErr)
}
zap.S().Debugf("StateManager: parent (top) block ID: %s, ts: %d", lastAppliedBlock.BlockID().String(), lastAppliedBlock.Timestamp)
height, err := s.Height()
if err != nil {
return nil, wrapErr(RetrievalError, err)
height, hErr := s.Height()
if hErr != nil {
return nil, wrapErr(RetrievalError, hErr)
}
headers := make([]proto.BlockHeader, blocksNumber)

Expand All @@ -1817,47 +1830,9 @@ func (s *stateManager) addBlocks() (*proto.Block, error) {
return nil, wrapErr(DeserializationError, errCurBlock)
}

if err = s.beforeAddingBlock(block, lastAppliedBlock, blockchainCurHeight, chans); err != nil {
return nil, err
}
sh, errSh := s.stor.stateHashes.newestSnapshotStateHash(blockchainCurHeight)
if errSh != nil {
return nil, errors.Wrapf(errSh, "failed to get newest snapshot state hash for height %d",
blockchainCurHeight,
)
}

// Generate blockchain fix snapshots for the applying block.
fixSnapshots, gbfErr := s.generateBlockchainFix(blockchainCurHeight+1, block.BlockID(), false)
if gbfErr != nil {
return nil, errors.Wrapf(gbfErr, "failed to generate blockchain fix snapshots at block %s",
block.BlockID().String(),
)
}
if sbfErr := s.saveBlockchainFix(block.BlockID(), fixSnapshots); sbfErr != nil {
return nil, wrapErr(ModificationError, errors.Wrapf(sbfErr, "failed to save blockchain fix for block %s",
block.BlockID().String()),
)
}

fixSnapshotsToInitialHash := fixSnapshots // at the block applying stage fix snapshots are only used for hashing
// Save block to storage, check its transactions, create and save balance diffs for its transactions.
addErr := s.addNewBlock(
block, lastAppliedBlock, chans, blockchainCurHeight, optionalSnapshot, fixSnapshotsToInitialHash, sh)
if addErr != nil {
return nil, addErr
}
if fixErr := s.applyBlockchainFix(block.BlockID(), fixSnapshots); fixErr != nil {
return nil, errors.Wrapf(fixErr, "failed to apply fix snapshots after block %s applying",
block.BlockID().String(),
)
}
blockchainCurHeight++ // we've just added a new block and applied blockchain fix, so we have a new height

if s.needToFinishVotingPeriod(blockchainCurHeight) {
// If we need to finish voting period on the next block (h+1) then
// we have to check that protobuf will be activated on next block
s.checkProtobufActivation(blockchainCurHeight + 1)
pErr := s.processBlockInPack(block, optionalSnapshot, lastAppliedBlock, blockchainCurHeight, chans)
if pErr != nil {
return nil, pErr
}

// Prepare for the next iteration.
Expand All @@ -1877,12 +1852,12 @@ func (s *stateManager) addBlocks() (*proto.Block, error) {
return nil, wrapErr(ModificationError, shErr)
}
// Validate consensus (i.e. that all the new blocks were mined fairly).
if err = s.cv.ValidateHeadersBatch(headers[:pos], height); err != nil {
return nil, wrapErr(ValidationError, err)
if vErr := s.cv.ValidateHeadersBatch(headers[:pos], height); vErr != nil {
return nil, wrapErr(ValidationError, vErr)
}
// After everything is validated, save all the changes to DB.
if err = s.flush(); err != nil {
return nil, wrapErr(ModificationError, err)
if fErr := s.flush(); fErr != nil {
return nil, wrapErr(ModificationError, fErr)
}
zap.S().Infof(
"Height: %d; Block ID: %s, GenSig: %s, ts: %d",
Expand All @@ -1894,6 +1869,58 @@ func (s *stateManager) addBlocks() (*proto.Block, error) {
return lastAppliedBlock, nil
}

func (s *stateManager) processBlockInPack(
block *proto.Block,
optionalSnapshot *proto.BlockSnapshot,
lastAppliedBlock *proto.Block,
blockchainCurHeight uint64,
chans *verifierChans,
) error {
if badErr := s.beforeAddingBlock(block, lastAppliedBlock, blockchainCurHeight, chans); badErr != nil {
return badErr
}
sh, errSh := s.stor.stateHashes.newestSnapshotStateHash(blockchainCurHeight)
if errSh != nil {
return errors.Wrapf(errSh, "failed to get newest snapshot state hash for height %d",
blockchainCurHeight,
)
}

// Generate blockchain fix snapshots for the applying block.
fixSnapshots, gbfErr := s.generateBlockchainFix(blockchainCurHeight+1, block.BlockID(), false)
if gbfErr != nil {
return errors.Wrapf(gbfErr, "failed to generate blockchain fix snapshots at block %s",
block.BlockID().String(),
)
}
if sbfErr := s.saveBlockchainFix(block.BlockID(), fixSnapshots); sbfErr != nil {
return wrapErr(ModificationError, errors.Wrapf(sbfErr, "failed to save blockchain fix for block %s",
block.BlockID().String()),
)
}

fixSnapshotsToInitialHash := fixSnapshots // at the block applying stage fix snapshots are only used for hashing
// Save block to storage, check its transactions, create and save balance diffs for its transactions.
addErr := s.addNewBlock(
block, lastAppliedBlock, chans, blockchainCurHeight, optionalSnapshot, fixSnapshotsToInitialHash, sh)
if addErr != nil {
return addErr
}
if fixErr := s.applyBlockchainFix(block.BlockID(), fixSnapshots); fixErr != nil {
return errors.Wrapf(fixErr, "failed to apply fix snapshots after block %s applying",
block.BlockID().String(),
)
}
blockchainCurHeight++ // we've just added a new block and applied blockchain fix, so we have a new height

if s.needToFinishVotingPeriod(blockchainCurHeight) {
// If we need to finish voting period on the next block (h+1) then
// we have to check that protobuf will be activated on next block
s.checkProtobufActivation(blockchainCurHeight + 1)
}
return nil
}

func (s *stateManager) beforeAddingBlock(
block, lastAppliedBlock *proto.Block,
blockchainCurHeight proto.Height,
Expand Down Expand Up @@ -2973,15 +3000,9 @@ func (s *stateManager) TotalWavesAmount(height proto.Height) (uint64, error) {
return 0, err
}

var rewardBoostActivationHeight uint64
var rewardBoostLastHeight uint64
rewardBoostActivated := s.stor.features.isActivatedAtHeight(int16(settings.BoostBlockReward), height)
if rewardBoostActivated {
rewardBoostActivationHeight, err = s.stor.features.activationHeight(int16(settings.BoostBlockReward))
if err != nil {
return 0, err
}
rewardBoostLastHeight = rewardBoostActivationHeight + s.settings.BlockRewardBoostPeriod - 1
rewardBoostActivationHeight, rewardBoostLastHeight, err := rewardBoostFeatureInfo(height, s.stor.features, s.settings)
if err != nil {
return 0, err
}

amount, err := s.stor.monetaryPolicy.totalAmountAtHeight(height, initialTotalAmount, blockRewardActivationHeight,
Expand All @@ -2992,6 +3013,23 @@ func (s *stateManager) TotalWavesAmount(height proto.Height) (uint64, error) {
return amount, nil
}

func rewardBoostFeatureInfo(
h proto.Height,
feat featuresState,
bs *settings.BlockchainSettings,
) (proto.Height, proto.Height, error) {
rewardBoostActivated := feat.isActivatedAtHeight(int16(settings.BoostBlockReward), h)
if !rewardBoostActivated {
return 0, 0, nil
}
rewardBoostActivationHeight, err := feat.activationHeight(int16(settings.BoostBlockReward))
if err != nil {
return 0, 0, err
}
rewardBoostLastHeight := rewardBoostActivationHeight + bs.BlockRewardBoostPeriod - 1
return rewardBoostActivationHeight, rewardBoostLastHeight, nil
}

func (s *stateManager) SnapshotsAtHeight(height proto.Height) (proto.BlockSnapshot, error) {
return s.stor.snapshots.getSnapshots(height)
}
Expand Down
Loading