From 5ca4a7f76ac91e97f4ec5c4a7f9bedcd3c020f47 Mon Sep 17 00:00:00 2001 From: Daniil Lashin <3121312+danil-lashin@users.noreply.github.com> Date: Wed, 22 Jan 2020 08:44:28 +0300 Subject: [PATCH] Hot fixes --- CHANGELOG.md | 12 ++++++ cmd/minter/cmd/node.go | 2 +- config/config.go | 2 + core/minter/minter.go | 10 +++++ core/state/statedb.go | 98 ++++++++++++++++++++++++------------------ upgrades/blocks.go | 4 ++ version/version.go | 4 +- 7 files changed, 88 insertions(+), 44 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0dca8d501..e558519b5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,17 @@ # Changelog +## 1.0.5 + +BUG FIXES + +- [core] Fix coin liquidation issue + +IMPROVEMENT + +- [core] Add grace period from 4262457 to 4262500 block +- [cmd] Set start time at 7:00 AM Wednesday, January 22, 2020 +- [config] Add halt_height param + ## 1.0.4 IMPROVEMENT diff --git a/cmd/minter/cmd/node.go b/cmd/minter/cmd/node.go index 5eb7fa95e..0dbf167b9 100644 --- a/cmd/minter/cmd/node.go +++ b/cmd/minter/cmd/node.go @@ -34,7 +34,7 @@ var RunNode = &cobra.Command{ func runNode() error { now := time.Now() - startTime := time.Date(2019, time.June, 5, 17, 0, 0, 0, time.UTC) + startTime := time.Date(2020, time.January, 22, 7, 0, 0, 0, time.UTC) if startTime.After(now) { fmt.Printf("Start time is in the future, sleeping until %s", startTime) time.Sleep(startTime.Sub(now)) diff --git a/config/config.go b/config/config.go index 5b19be0e3..03eec6815 100644 --- a/config/config.go +++ b/config/config.go @@ -239,6 +239,8 @@ type BaseConfig struct { APISimultaneousRequests int `mapstructure:"api_simultaneous_requests"` LogPath string `mapstructure:"log_path"` + + HaltHeight int `mapstructure:"halt_height"` } // DefaultBaseConfig returns a default base configuration for a Tendermint node diff --git a/core/minter/minter.go b/core/minter/minter.go index 7b9dc7561..40bb4beb2 100644 --- a/core/minter/minter.go +++ b/core/minter/minter.go @@ -2,6 +2,7 @@ package minter import ( "bytes" + "fmt" "github.com/MinterTeam/go-amino" "github.com/MinterTeam/minter-go-node/cmd/utils" "github.com/MinterTeam/minter-go-node/config" @@ -65,6 +66,8 @@ type Blockchain struct { lock sync.RWMutex wg sync.WaitGroup // wg is used for graceful node shutdown stopped uint32 + + haltHeight uint64 } // Creates Minter Blockchain instance, should be only called once @@ -96,6 +99,8 @@ func NewMinterBlockchain(cfg *config.Config) *Blockchain { rewards.SetStartHeight(applicationDB.GetStartHeight()) validators.SetStartHeight(applicationDB.GetStartHeight()) + blockchain.haltHeight = uint64(cfg.HaltHeight) + return blockchain } @@ -154,6 +159,11 @@ func (app *Blockchain) BeginBlock(req abciTypes.RequestBeginBlock) abciTypes.Res } } + if app.haltHeight > 0 && height >= app.haltHeight { + app.wg.Done() + panic(fmt.Sprintf("Application halted at height %d", height)) + } + // compute max gas app.updateBlocksTimeDelta(height, 3) maxGas := app.calcMaxGas(height) diff --git a/core/state/statedb.go b/core/state/statedb.go index 77791e4ba..0a63c791f 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -1231,7 +1231,7 @@ func (s *StateDB) SetValidatorAbsent(address [20]byte) { for i := range vals.data { validator := &vals.data[i] if validator.GetAddress() == address { - + var coinsToSanitize []types.CoinSymbol candidates := s.getStateCandidates() var candidate *Candidate @@ -1252,55 +1252,71 @@ func (s *StateDB) SetValidatorAbsent(address [20]byte) { validator.AbsentTimes.SetIndex(int(s.height)%ValidatorMaxAbsentWindow, true) + isGracePeriod := false + if s.height > upgrades.GracePeriod1From && s.height < upgrades.GracePeriod1To { + isGracePeriod = true + } + if validator.CountAbsentTimes() > ValidatorMaxAbsentTimes { candidate.Status = CandidateStatusOffline validator.AbsentTimes = types.NewBitArray(ValidatorMaxAbsentWindow) validator.toDrop = true - totalStake := big.NewInt(0) - - for j, stake := range candidate.Stakes { - newValue := big.NewInt(0).Set(stake.Value) - newValue.Mul(newValue, big.NewInt(99)) - newValue.Div(newValue, big.NewInt(100)) - - slashed := big.NewInt(0).Set(stake.Value) - slashed.Sub(slashed, newValue) - - if !stake.Coin.IsBaseCoin() { - coin := s.GetStateCoin(stake.Coin).Data() - ret := formula.CalculateSaleReturn(coin.Volume, coin.ReserveBalance, coin.Crr, slashed) - - s.SubCoinVolume(coin.Symbol, slashed) - s.SubCoinReserve(coin.Symbol, ret) - s.SanitizeCoin(stake.Coin) - - s.AddTotalSlashed(ret) - } else { - s.AddTotalSlashed(slashed) + if !isGracePeriod { + totalStake := big.NewInt(0) + + for j, stake := range candidate.Stakes { + newValue := big.NewInt(0).Set(stake.Value) + newValue.Mul(newValue, big.NewInt(99)) + newValue.Div(newValue, big.NewInt(100)) + + slashed := big.NewInt(0).Set(stake.Value) + slashed.Sub(slashed, newValue) + + if !stake.Coin.IsBaseCoin() { + coin := s.GetStateCoin(stake.Coin).Data() + ret := formula.CalculateSaleReturn(coin.Volume, coin.ReserveBalance, coin.Crr, slashed) + + s.SubCoinVolume(coin.Symbol, slashed) + s.SubCoinReserve(coin.Symbol, ret) + if s.height <= upgrades.UpgradeBlock2 { + s.SanitizeCoin(stake.Coin) + } + coinsToSanitize = append(coinsToSanitize, stake.Coin) + + s.AddTotalSlashed(ret) + } else { + s.AddTotalSlashed(slashed) + } + + edb.AddEvent(s.height, events.SlashEvent{ + Address: stake.Owner, + Amount: slashed.Bytes(), + Coin: stake.Coin, + ValidatorPubKey: candidate.PubKey, + }) + + candidate.Stakes[j] = Stake{ + Owner: stake.Owner, + Coin: stake.Coin, + Value: newValue, + BipValue: big.NewInt(0), + } + totalStake.Add(totalStake, newValue) } - edb.AddEvent(s.height, events.SlashEvent{ - Address: stake.Owner, - Amount: slashed.Bytes(), - Coin: stake.Coin, - ValidatorPubKey: candidate.PubKey, - }) - - candidate.Stakes[j] = Stake{ - Owner: stake.Owner, - Coin: stake.Coin, - Value: newValue, - BipValue: big.NewInt(0), - } - totalStake.Add(totalStake, newValue) + validator.TotalBipStake = totalStake } - - validator.TotalBipStake = totalStake } s.setStateCandidates(candidates) s.MarkStateCandidateDirty() + + if s.height > upgrades.UpgradeBlock2 { + for _, coin := range coinsToSanitize { + s.SanitizeCoin(coin) + } + } } } @@ -1757,13 +1773,13 @@ func (s *StateDB) deleteCoin(symbol types.CoinSymbol) { coinToDelete.SubReserve(ret) coinToDelete.SubVolume(stake.Value) - stake := candidate.GetStakeOfAddress(stake.Owner, types.GetBaseCoin()) - if stake == nil { + st := candidate.GetStakeOfAddress(stake.Owner, types.GetBaseCoin()) + if st == nil { candidate.Stakes[j].Value = ret candidate.Stakes[j].Coin = types.GetBaseCoin() } else { candidate.Stakes[j].Value = big.NewInt(0) - stake.Value.Add(stake.Value, ret) + st.Value.Add(st.Value, ret) } } } diff --git a/upgrades/blocks.go b/upgrades/blocks.go index a58c28e47..bfb30eba1 100644 --- a/upgrades/blocks.go +++ b/upgrades/blocks.go @@ -2,3 +2,7 @@ package upgrades const UpgradeBlock0 = 5760 const UpgradeBlock1 = 250000 +const UpgradeBlock2 = 4262457 + +const GracePeriod1From = 4262457 +const GracePeriod1To = 4262500 diff --git a/version/version.go b/version/version.go index 636e89184..7d852eb56 100755 --- a/version/version.go +++ b/version/version.go @@ -4,14 +4,14 @@ package version const ( Maj = "1" Min = "0" - Fix = "4" + Fix = "5" AppVer = 5 ) var ( // Must be a string because scripts like dist.sh read this file. - Version = "1.0.4" + Version = "1.0.5" // GitCommit is the current HEAD set using ldflags. GitCommit string