From 369a02ae9022c5a23c710ae98073f297c26687f7 Mon Sep 17 00:00:00 2001 From: klim0v Date: Fri, 16 Apr 2021 11:15:44 +0300 Subject: [PATCH 01/15] CHANGELOG.md --- coreV2/minter/blockchain.go | 135 ++++++++++++++++++++---------------- coreV2/minter/minter.go | 68 +++++++++++++++++- 2 files changed, 144 insertions(+), 59 deletions(-) diff --git a/coreV2/minter/blockchain.go b/coreV2/minter/blockchain.go index c32f7f848..b65273838 100644 --- a/coreV2/minter/blockchain.go +++ b/coreV2/minter/blockchain.go @@ -289,65 +289,84 @@ func (blockchain *Blockchain) EndBlock(req abciTypes.RequestEndBlock) abciTypes. if height%blockchain.updateStakesAndPayRewardsPeriod == 0 { blockchain.stateDeliver.Validators.PayRewards() } + currentV := blockchain.appDB.GetVersion(height) - if prices := blockchain.isUpdateCommissionsBlock(height); len(prices) != 0 { - blockchain.stateDeliver.Commission.SetNewCommissions(prices) - price := blockchain.stateDeliver.Commission.GetCommissions() - blockchain.eventsDB.AddEvent(&eventsdb.UpdateCommissionsEvent{ - Coin: uint64(price.Coin), - PayloadByte: price.PayloadByte.String(), - Send: price.Send.String(), - BuyBancor: price.BuyBancor.String(), - SellBancor: price.SellBancor.String(), - SellAllBancor: price.SellAllBancor.String(), - BuyPoolBase: price.BuyPoolBase.String(), - BuyPoolDelta: price.BuyPoolDelta.String(), - SellPoolBase: price.SellPoolBase.String(), - SellPoolDelta: price.SellPoolDelta.String(), - SellAllPoolBase: price.SellAllPoolBase.String(), - SellAllPoolDelta: price.SellAllPoolDelta.String(), - CreateTicker3: price.CreateTicker3.String(), - CreateTicker4: price.CreateTicker4.String(), - CreateTicker5: price.CreateTicker5.String(), - CreateTicker6: price.CreateTicker6.String(), - CreateTicker7_10: price.CreateTicker7to10.String(), - CreateCoin: price.CreateCoin.String(), - CreateToken: price.CreateToken.String(), - RecreateCoin: price.RecreateCoin.String(), - RecreateToken: price.RecreateToken.String(), - DeclareCandidacy: price.DeclareCandidacy.String(), - Delegate: price.Delegate.String(), - Unbond: price.Unbond.String(), - RedeemCheck: price.RedeemCheck.String(), - SetCandidateOn: price.SetCandidateOn.String(), - SetCandidateOff: price.SetCandidateOff.String(), - CreateMultisig: price.CreateMultisig.String(), - MultisendBase: price.MultisendBase.String(), - MultisendDelta: price.MultisendDelta.String(), - EditCandidate: price.EditCandidate.String(), - SetHaltBlock: price.SetHaltBlock.String(), - EditTickerOwner: price.EditTickerOwner.String(), - EditMultisig: price.EditMultisig.String(), - EditCandidatePublicKey: price.EditCandidatePublicKey.String(), - CreateSwapPool: price.CreateSwapPool.String(), - AddLiquidity: price.AddLiquidity.String(), - RemoveLiquidity: price.RemoveLiquidity.String(), - EditCandidateCommission: price.EditCandidateCommission.String(), - MintToken: price.MintToken.String(), - BurnToken: price.BurnToken.String(), - VoteCommission: price.VoteCommission.String(), - VoteUpdate: price.VoteUpdate.String(), - }) - } - blockchain.stateDeliver.Commission.Delete(height) - - if v, ok := blockchain.isUpdateNetworkBlock(height); ok { - blockchain.appDB.AddVersion(v, height) - blockchain.eventsDB.AddEvent(&eventsdb.UpdateNetworkEvent{ - Version: v, - }) - } - blockchain.stateDeliver.Updates.Delete(height) + { + var updateCommissionsBlockPrices []byte + if currentV == "v210" { // todo: change to != "" + updateCommissionsBlockPrices = blockchain.isUpdateCommissionsBlock(height) + } else { + updateCommissionsBlockPrices = blockchain.isUpdateCommissionsBlockV2(height) + } + if prices := updateCommissionsBlockPrices; len(prices) != 0 { + blockchain.stateDeliver.Commission.SetNewCommissions(prices) + price := blockchain.stateDeliver.Commission.GetCommissions() + blockchain.eventsDB.AddEvent(&eventsdb.UpdateCommissionsEvent{ + Coin: uint64(price.Coin), + PayloadByte: price.PayloadByte.String(), + Send: price.Send.String(), + BuyBancor: price.BuyBancor.String(), + SellBancor: price.SellBancor.String(), + SellAllBancor: price.SellAllBancor.String(), + BuyPoolBase: price.BuyPoolBase.String(), + BuyPoolDelta: price.BuyPoolDelta.String(), + SellPoolBase: price.SellPoolBase.String(), + SellPoolDelta: price.SellPoolDelta.String(), + SellAllPoolBase: price.SellAllPoolBase.String(), + SellAllPoolDelta: price.SellAllPoolDelta.String(), + CreateTicker3: price.CreateTicker3.String(), + CreateTicker4: price.CreateTicker4.String(), + CreateTicker5: price.CreateTicker5.String(), + CreateTicker6: price.CreateTicker6.String(), + CreateTicker7_10: price.CreateTicker7to10.String(), + CreateCoin: price.CreateCoin.String(), + CreateToken: price.CreateToken.String(), + RecreateCoin: price.RecreateCoin.String(), + RecreateToken: price.RecreateToken.String(), + DeclareCandidacy: price.DeclareCandidacy.String(), + Delegate: price.Delegate.String(), + Unbond: price.Unbond.String(), + RedeemCheck: price.RedeemCheck.String(), + SetCandidateOn: price.SetCandidateOn.String(), + SetCandidateOff: price.SetCandidateOff.String(), + CreateMultisig: price.CreateMultisig.String(), + MultisendBase: price.MultisendBase.String(), + MultisendDelta: price.MultisendDelta.String(), + EditCandidate: price.EditCandidate.String(), + SetHaltBlock: price.SetHaltBlock.String(), + EditTickerOwner: price.EditTickerOwner.String(), + EditMultisig: price.EditMultisig.String(), + EditCandidatePublicKey: price.EditCandidatePublicKey.String(), + CreateSwapPool: price.CreateSwapPool.String(), + AddLiquidity: price.AddLiquidity.String(), + RemoveLiquidity: price.RemoveLiquidity.String(), + EditCandidateCommission: price.EditCandidateCommission.String(), + MintToken: price.MintToken.String(), + BurnToken: price.BurnToken.String(), + VoteCommission: price.VoteCommission.String(), + VoteUpdate: price.VoteUpdate.String(), + }) + } + blockchain.stateDeliver.Commission.Delete(height) + } + + { + var v string + var ok bool + if currentV == "v210" { // todo: change to != "" + v, ok = blockchain.isUpdateNetworkBlock(height) + } else { + v, ok = blockchain.isUpdateNetworkBlock(height) + } + + if ok { + blockchain.appDB.AddVersion(v, height) + blockchain.eventsDB.AddEvent(&eventsdb.UpdateNetworkEvent{ + Version: v, + }) + } + blockchain.stateDeliver.Updates.Delete(height) + } hasChangedPublicKeys := false if blockchain.stateDeliver.Candidates.IsChangedPublicKeys() { diff --git a/coreV2/minter/minter.go b/coreV2/minter/minter.go index 1ad9e5d31..d41c50c42 100644 --- a/coreV2/minter/minter.go +++ b/coreV2/minter/minter.go @@ -326,16 +326,82 @@ func (blockchain *Blockchain) isUpdateCommissionsBlock(height uint64) []byte { return nil } +func (blockchain *Blockchain) isUpdateCommissionsBlockV2(height uint64) []byte { + commissions := blockchain.stateDeliver.Commission.GetVotes(height) + if len(commissions) == 0 { + return nil + } + // calculate total power of validators + maxVotingResult := big.NewFloat(0) + + var price string + for _, commission := range commissions { + totalVotedPower := big.NewInt(0) + for _, vote := range commission.Votes { + if power, ok := blockchain.validatorsPowers[vote]; ok { + totalVotedPower.Add(totalVotedPower, power) + } + } + votingResult := new(big.Float).Quo( + new(big.Float).SetInt(totalVotedPower), + new(big.Float).SetInt(blockchain.totalPower), + ) + + if maxVotingResult.Cmp(votingResult) == -1 { + maxVotingResult = votingResult + price = commission.Price + } + } + if maxVotingResult.Cmp(big.NewFloat(votingPowerConsensus)) == 1 { + return []byte(price) + } + + return nil +} + func (blockchain *Blockchain) isUpdateNetworkBlock(height uint64) (string, bool) { versions := blockchain.stateDeliver.Updates.GetVotes(height) if len(versions) == 0 { return "", false } // calculate total power of validators - maxVotingResult, totalVotedPower := big.NewFloat(0), big.NewInt(0) + maxVotingResult := big.NewFloat(0) + totalVotedPower := big.NewInt(0) + + var version string + for _, v := range versions { + for _, vote := range v.Votes { + if power, ok := blockchain.validatorsPowers[vote]; ok { + totalVotedPower.Add(totalVotedPower, power) + } + } + votingResult := new(big.Float).Quo( + new(big.Float).SetInt(totalVotedPower), + new(big.Float).SetInt(blockchain.totalPower), + ) + + if maxVotingResult.Cmp(votingResult) == -1 { + maxVotingResult = votingResult + version = v.Version + } + } + if maxVotingResult.Cmp(big.NewFloat(votingPowerConsensus)) == 1 { + return version, true + } + return "", false +} + +func (blockchain *Blockchain) isUpdateNetworkBlockV2(height uint64) (string, bool) { + versions := blockchain.stateDeliver.Updates.GetVotes(height) + if len(versions) == 0 { + return "", false + } + // calculate total power of validators + maxVotingResult := big.NewFloat(0) var version string for _, v := range versions { + totalVotedPower := big.NewInt(0) for _, vote := range v.Votes { if power, ok := blockchain.validatorsPowers[vote]; ok { totalVotedPower.Add(totalVotedPower, power) From c111761355d39665c2d90d2833a6e978fa8ec52d Mon Sep 17 00:00:00 2001 From: klim0v Date: Fri, 16 Apr 2021 11:52:03 +0300 Subject: [PATCH 02/15] refactor --- coreV2/minter/blockchain.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/coreV2/minter/blockchain.go b/coreV2/minter/blockchain.go index b65273838..31e530e13 100644 --- a/coreV2/minter/blockchain.go +++ b/coreV2/minter/blockchain.go @@ -293,7 +293,7 @@ func (blockchain *Blockchain) EndBlock(req abciTypes.RequestEndBlock) abciTypes. { var updateCommissionsBlockPrices []byte - if currentV == "v210" { // todo: change to != "" + if currentV == "" { updateCommissionsBlockPrices = blockchain.isUpdateCommissionsBlock(height) } else { updateCommissionsBlockPrices = blockchain.isUpdateCommissionsBlockV2(height) @@ -353,7 +353,7 @@ func (blockchain *Blockchain) EndBlock(req abciTypes.RequestEndBlock) abciTypes. { var v string var ok bool - if currentV == "v210" { // todo: change to != "" + if currentV == "" { v, ok = blockchain.isUpdateNetworkBlock(height) } else { v, ok = blockchain.isUpdateNetworkBlock(height) From 61e36ba54a33ec74bbb1c5d630974e28cf6a5c64 Mon Sep 17 00:00:00 2001 From: klim0v Date: Fri, 16 Apr 2021 11:55:18 +0300 Subject: [PATCH 03/15] CHANGELOG.md --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c17aa81c8..e8adcadbe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## [v2.1.0](https://github.com/MinterTeam/minter-go-node/tree/v2.1.0) + +[Full Changelog](https://github.com/MinterTeam/minter-go-node/compare/v2.0.3...v2.1.0) + +### Fixed + +- Correction of votes + ## [v2.0.3](https://github.com/MinterTeam/minter-go-node/tree/v2.0.3) [Full Changelog](https://github.com/MinterTeam/minter-go-node/compare/v2.0.2...v2.0.3) From fc9e9f169caaa29030afd163950b7bb6eb28ae01 Mon Sep 17 00:00:00 2001 From: klim0v Date: Fri, 16 Apr 2021 13:17:26 +0300 Subject: [PATCH 04/15] tests --- coreV2/minter/blockchain.go | 2 +- coreV2/minter/minter.go | 2 + tests/byz_test.go | 4 +- tests/helpers_test.go | 33 +- tests/send_test.go | 6 +- tests/votes_test.go | 805 ++++++++++++++++++++++++++++++++++++ 6 files changed, 836 insertions(+), 16 deletions(-) create mode 100644 tests/votes_test.go diff --git a/coreV2/minter/blockchain.go b/coreV2/minter/blockchain.go index 31e530e13..b33996ca4 100644 --- a/coreV2/minter/blockchain.go +++ b/coreV2/minter/blockchain.go @@ -356,7 +356,7 @@ func (blockchain *Blockchain) EndBlock(req abciTypes.RequestEndBlock) abciTypes. if currentV == "" { v, ok = blockchain.isUpdateNetworkBlock(height) } else { - v, ok = blockchain.isUpdateNetworkBlock(height) + v, ok = blockchain.isUpdateNetworkBlockV2(height) } if ok { diff --git a/coreV2/minter/minter.go b/coreV2/minter/minter.go index d41c50c42..9deaecac8 100644 --- a/coreV2/minter/minter.go +++ b/coreV2/minter/minter.go @@ -294,6 +294,7 @@ func (blockchain *Blockchain) isApplicationHalted(height uint64) bool { return false } +// Deprecated func (blockchain *Blockchain) isUpdateCommissionsBlock(height uint64) []byte { commissions := blockchain.stateDeliver.Commission.GetVotes(height) if len(commissions) == 0 { @@ -359,6 +360,7 @@ func (blockchain *Blockchain) isUpdateCommissionsBlockV2(height uint64) []byte { return nil } +// Deprecated func (blockchain *Blockchain) isUpdateNetworkBlock(height uint64) (string, bool) { versions := blockchain.stateDeliver.Updates.GetVotes(height) if len(versions) == 0 { diff --git a/tests/byz_test.go b/tests/byz_test.go index 79c0e8f0c..469918aa8 100644 --- a/tests/byz_test.go +++ b/tests/byz_test.go @@ -85,8 +85,8 @@ func TestBlockchain_ByzantineValidators(t *testing.T) { app.BeginBlock(req) // SendBeginBlock(app) // send BeginBlock - SendEndBlock(app) // send EndBlock - SendCommit(app) // send Commit + SendEndBlock(app, 1) // send EndBlock + SendCommit(app) // send Commit if validator := app.CurrentState().Validators().GetByPublicKey([32]byte{1}); validator != nil { t.Error("validator exists") diff --git a/tests/helpers_test.go b/tests/helpers_test.go index 474825852..dc65622d8 100644 --- a/tests/helpers_test.go +++ b/tests/helpers_test.go @@ -27,12 +27,14 @@ func CreateApp(state types.AppState) *minter.Blockchain { cfg := config.GetConfig(storage.GetMinterHome()) cfg.DBBackend = "memdb" app := minter.NewMinterBlockchain(storage, cfg, nil, 120) + var updates []tmTypes.ValidatorUpdate + for _, validator := range state.Validators { + updates = append(updates, tmTypes.Ed25519ValidatorUpdate(validator.PubKey.Bytes(), 1)) + } app.InitChain(tmTypes.RequestInitChain{ - Time: time.Now(), - ChainId: "test", - Validators: []tmTypes.ValidatorUpdate{ - tmTypes.Ed25519ValidatorUpdate([]byte{}, 1), - }, + Time: time.Now(), + ChainId: "test", + Validators: updates, InitialHeight: 1, AppStateBytes: jsonState, }) @@ -46,13 +48,24 @@ func SendCommit(app *minter.Blockchain) tmTypes.ResponseCommit { } // SendBeginBlock sends BeginBlock message to given Blockchain instance -func SendBeginBlock(app *minter.Blockchain) tmTypes.ResponseBeginBlock { +func SendBeginBlock(app *minter.Blockchain, height int64) tmTypes.ResponseBeginBlock { + var voteInfos []tmTypes.VoteInfo + for _, validator := range app.CurrentState().Validators().GetValidators() { + address := validator.GetAddress() + voteInfos = append(voteInfos, tmTypes.VoteInfo{ + Validator: tmTypes.Validator{ + Address: address[:], + Power: 0, + }, + SignedLastBlock: true, + }) + } return app.BeginBlock(tmTypes.RequestBeginBlock{ Hash: nil, Header: tmTypes1.Header{ Version: version.Consensus{}, ChainID: "", - Height: 1, + Height: height, Time: time.Time{}, LastBlockId: tmTypes1.BlockID{}, LastCommitHash: nil, @@ -67,16 +80,16 @@ func SendBeginBlock(app *minter.Blockchain) tmTypes.ResponseBeginBlock { }, LastCommitInfo: tmTypes.LastCommitInfo{ Round: 0, - Votes: nil, + Votes: voteInfos, }, ByzantineValidators: nil, }) } // SendEndBlock sends EndBlock message to given Blockchain instance -func SendEndBlock(app *minter.Blockchain) tmTypes.ResponseEndBlock { +func SendEndBlock(app *minter.Blockchain, height int64) tmTypes.ResponseEndBlock { return app.EndBlock(tmTypes.RequestEndBlock{ - Height: 0, + Height: height, }) } diff --git a/tests/send_test.go b/tests/send_test.go index ca11aca28..69990de08 100644 --- a/tests/send_test.go +++ b/tests/send_test.go @@ -28,7 +28,7 @@ func TestSend(t *testing.T) { }) app := CreateApp(state) // create application - SendBeginBlock(app) // send BeginBlock + SendBeginBlock(app, 1) // send BeginBlock recipient, _ := CreateAddress() // generate recipient value := big.NewInt(1) @@ -46,8 +46,8 @@ func TestSend(t *testing.T) { t.Fatalf("Response code is not OK: %s, %d", response.Log, response.Code) } - SendEndBlock(app) // send EndBlock - SendCommit(app) // send Commit + SendEndBlock(app, 1) // send EndBlock + SendCommit(app) // send Commit // check recipient's balance { diff --git a/tests/votes_test.go b/tests/votes_test.go new file mode 100644 index 000000000..9a017df60 --- /dev/null +++ b/tests/votes_test.go @@ -0,0 +1,805 @@ +package tests + +import ( + "github.com/MinterTeam/minter-go-node/coreV2/code" + "github.com/MinterTeam/minter-go-node/coreV2/transaction" + "github.com/MinterTeam/minter-go-node/coreV2/types" + "github.com/MinterTeam/minter-go-node/crypto" + "github.com/MinterTeam/minter-go-node/helpers" + "math/big" + "testing" +) + +func TestVoteCommissionFail(t *testing.T) { + privateKey1, _ := crypto.GenerateKey() // create accounts for test + address1 := crypto.PubkeyToAddress(privateKey1.PublicKey) + privateKey2, _ := crypto.GenerateKey() // create accounts for test + address2 := crypto.PubkeyToAddress(privateKey2.PublicKey) + privateKey3, _ := crypto.GenerateKey() // create accounts for test + address3 := crypto.PubkeyToAddress(privateKey3.PublicKey) + privateKey4, _ := crypto.GenerateKey() // create accounts for test + address4 := crypto.PubkeyToAddress(privateKey4.PublicKey) + privateKey5, _ := crypto.GenerateKey() // create accounts for test + address5 := crypto.PubkeyToAddress(privateKey5.PublicKey) + privateKey6, _ := crypto.GenerateKey() // create accounts for test + address6 := crypto.PubkeyToAddress(privateKey6.PublicKey) + + state := DefaultAppState() // generate default state + + // add address to genesis state + state.Accounts = append(state.Accounts, + types.Account{ + Address: address1, + Balance: []types.Balance{ + { + Coin: uint64(types.GetBaseCoinID()), + Value: helpers.StringToBigInt("100000000000000000000").String(), + }, + }, + Nonce: 0, + MultisigData: nil, + }, + types.Account{ + Address: address2, + Balance: []types.Balance{ + { + Coin: uint64(types.GetBaseCoinID()), + Value: helpers.StringToBigInt("100000000000000000000").String(), + }, + }, + Nonce: 0, + MultisigData: nil, + }, + types.Account{ + Address: address3, + Balance: []types.Balance{ + { + Coin: uint64(types.GetBaseCoinID()), + Value: helpers.StringToBigInt("100000000000000000000").String(), + }, + }, + Nonce: 0, + MultisigData: nil, + }, + types.Account{ + Address: address4, + Balance: []types.Balance{ + { + Coin: uint64(types.GetBaseCoinID()), + Value: helpers.StringToBigInt("100000000000000000000").String(), + }, + }, + Nonce: 0, + MultisigData: nil, + }, + types.Account{ + Address: address5, + Balance: []types.Balance{ + { + Coin: uint64(types.GetBaseCoinID()), + Value: helpers.StringToBigInt("100000000000000000000").String(), + }, + }, + Nonce: 0, + MultisigData: nil, + }, + types.Account{ + Address: address6, + Balance: []types.Balance{ + { + Coin: uint64(types.GetBaseCoinID()), + Value: helpers.StringToBigInt("100000000000000000000").String(), + }, + }, + Nonce: 0, + MultisigData: nil, + }, + ) + stake := helpers.BipToPip(big.NewInt(10000)).String() + state.Validators = append(state.Validators, + types.Validator{ + TotalBipStake: stake, + PubKey: types.Pubkey{1}, + AccumReward: "10", + AbsentTimes: nil, + }, + types.Validator{ + TotalBipStake: stake, + PubKey: types.Pubkey{2}, + AccumReward: "10", + AbsentTimes: nil, + }, + types.Validator{ + TotalBipStake: stake, + PubKey: types.Pubkey{3}, + AccumReward: "10", + AbsentTimes: nil, + }, + types.Validator{ + TotalBipStake: stake, + PubKey: types.Pubkey{4}, + AccumReward: "10", + AbsentTimes: nil, + }, + types.Validator{ + TotalBipStake: stake, + PubKey: types.Pubkey{5}, + AccumReward: "10", + AbsentTimes: nil, + }, + types.Validator{ + TotalBipStake: stake, + PubKey: types.Pubkey{6}, + AccumReward: "10", + AbsentTimes: nil, + }, + ) + state.Candidates = append(state.Candidates, + types.Candidate{ + ID: 1, + RewardAddress: address1, + OwnerAddress: address1, + ControlAddress: address1, + TotalBipStake: stake, + PubKey: types.Pubkey{1}, + Commission: 10, + Stakes: []types.Stake{ + { + Owner: types.Address{}, + Coin: 0, + Value: stake, + BipValue: stake, + }, + }, + Updates: nil, + Status: 2, + }, + types.Candidate{ + ID: 2, + RewardAddress: address2, + OwnerAddress: address2, + ControlAddress: address2, + TotalBipStake: stake, + PubKey: types.Pubkey{2}, + Commission: 10, + Stakes: []types.Stake{ + { + Owner: types.Address{}, + Coin: 0, + Value: stake, + BipValue: stake, + }, + }, + Updates: nil, + Status: 2, + }, + types.Candidate{ + ID: 3, + RewardAddress: address3, + OwnerAddress: address3, + ControlAddress: address3, + TotalBipStake: stake, + PubKey: types.Pubkey{3}, + Commission: 10, + Stakes: []types.Stake{ + { + Owner: types.Address{}, + Coin: 0, + Value: stake, + BipValue: stake, + }, + }, + Updates: nil, + Status: 2, + }, + types.Candidate{ + ID: 4, + RewardAddress: address4, + OwnerAddress: address4, + ControlAddress: address4, + TotalBipStake: stake, + PubKey: types.Pubkey{4}, + Commission: 10, + Stakes: []types.Stake{ + { + Owner: types.Address{}, + Coin: 0, + Value: stake, + BipValue: stake, + }, + }, + Updates: nil, + Status: 2, + }, + types.Candidate{ + ID: 5, + RewardAddress: address5, + OwnerAddress: address5, + ControlAddress: address5, + TotalBipStake: stake, + PubKey: types.Pubkey{5}, + Commission: 10, + Stakes: []types.Stake{ + { + Owner: types.Address{}, + Coin: 0, + Value: stake, + BipValue: stake, + }, + }, + Updates: nil, + Status: 2, + }, + types.Candidate{ + ID: 6, + RewardAddress: address6, + OwnerAddress: address6, + ControlAddress: address6, + TotalBipStake: stake, + PubKey: types.Pubkey{6}, + Commission: 10, + Stakes: []types.Stake{ + { + Owner: types.Address{}, + Coin: 0, + Value: stake, + BipValue: stake, + }, + }, + Updates: nil, + Status: 2, + }, + ) + app := CreateApp(state) // create application + + SendBeginBlock(app, 1) + SendEndBlock(app, 1) // send EndBlock + SendCommit(app) // send Commit + + SendBeginBlock(app, 2) + SendEndBlock(app, 2) // send EndBlock + SendCommit(app) // send Commit + + SendBeginBlock(app, 3) // send BeginBlock + { + tx := CreateTx(app, address1, transaction.TypeVoteCommission, transaction.VoteCommissionData{ + PubKey: types.Pubkey{1}, + Coin: types.GetBaseCoinID(), + Height: 5, + Send: big.NewInt(9999), + }) + + response := SendTx(app, SignTx(privateKey1, tx)) // compose and send tx + + // check that result is OK + if response.Code != code.OK { + t.Fatalf("Response code is not OK: %s, %d", response.Log, response.Code) + } + } + { + tx := CreateTx(app, address2, transaction.TypeVoteCommission, transaction.VoteCommissionData{ + PubKey: types.Pubkey{2}, + Coin: types.GetBaseCoinID(), + Height: 5, + Send: big.NewInt(9999), + }) + + response := SendTx(app, SignTx(privateKey2, tx)) // compose and send tx + + // check that result is OK + if response.Code != code.OK { + t.Fatalf("Response code is not OK: %s, %d", response.Log, response.Code) + } + } + { + tx := CreateTx(app, address3, transaction.TypeVoteCommission, transaction.VoteCommissionData{ + PubKey: types.Pubkey{3}, + Coin: types.GetBaseCoinID(), + Height: 5, + Send: big.NewInt(9999), + }) + + response := SendTx(app, SignTx(privateKey3, tx)) // compose and send tx + + // check that result is OK + if response.Code != code.OK { + t.Fatalf("Response code is not OK: %s, %d", response.Log, response.Code) + } + } + SendEndBlock(app, 3) // send EndBlock + SendCommit(app) // send Commit + + SendBeginBlock(app, 4) // send BeginBlock + + { + tx := CreateTx(app, address5, transaction.TypeVoteCommission, transaction.VoteCommissionData{ + PubKey: types.Pubkey{5}, + Coin: types.GetBaseCoinID(), + Height: 5, + Send: big.NewInt(9999), + }) + + response := SendTx(app, SignTx(privateKey5, tx)) // compose and send tx + + // check that result is OK + if response.Code != code.OK { + t.Fatalf("Response code is not OK: %s, %d", response.Log, response.Code) + } + } + { + tx := CreateTx(app, address6, transaction.TypeVoteCommission, transaction.VoteCommissionData{ + PubKey: types.Pubkey{6}, + Coin: types.GetBaseCoinID(), + Height: 5, + Send: big.NewInt(9999), + }) + + response := SendTx(app, SignTx(privateKey6, tx)) // compose and send tx + + // check that result is OK + if response.Code != code.OK { + t.Fatalf("Response code is not OK: %s, %d", response.Log, response.Code) + } + } + + { // Diff + tx := CreateTx(app, address4, transaction.TypeVoteCommission, transaction.VoteCommissionData{ + PubKey: types.Pubkey{4}, + Coin: types.GetBaseCoinID(), + Height: 5, + Send: big.NewInt(2e18), // Diff + }) + + response := SendTx(app, SignTx(privateKey4, tx)) // compose and send tx + + // check that result is OK + if response.Code != code.OK { + t.Fatalf("Response code is not OK: %s, %d", response.Log, response.Code) + } + } + SendEndBlock(app, 4) // send EndBlock + SendCommit(app) // send Commit + + SendBeginBlock(app, 5) + SendEndBlock(app, 5) // send EndBlock + SendCommit(app) // send Commit + + commissions := app.CurrentState().Commission().GetCommissions() + if commissions.Send.Cmp(big.NewInt(9999)) == 0 { + t.Fatalf("comission send want uncorrect. Expected %s, got %s", big.NewInt(2e18), commissions.Send) + } +} + +func TestVoteCommissionOKUpdateVersion(t *testing.T) { + privateKey1, _ := crypto.GenerateKey() // create accounts for test + address1 := crypto.PubkeyToAddress(privateKey1.PublicKey) + privateKey2, _ := crypto.GenerateKey() // create accounts for test + address2 := crypto.PubkeyToAddress(privateKey2.PublicKey) + privateKey3, _ := crypto.GenerateKey() // create accounts for test + address3 := crypto.PubkeyToAddress(privateKey3.PublicKey) + privateKey4, _ := crypto.GenerateKey() // create accounts for test + address4 := crypto.PubkeyToAddress(privateKey4.PublicKey) + privateKey5, _ := crypto.GenerateKey() // create accounts for test + address5 := crypto.PubkeyToAddress(privateKey5.PublicKey) + privateKey6, _ := crypto.GenerateKey() // create accounts for test + address6 := crypto.PubkeyToAddress(privateKey6.PublicKey) + + state := DefaultAppState() // generate default state + + // add address to genesis state + state.Accounts = append(state.Accounts, + types.Account{ + Address: address1, + Balance: []types.Balance{ + { + Coin: uint64(types.GetBaseCoinID()), + Value: helpers.StringToBigInt("100000000000000000000").String(), + }, + }, + Nonce: 0, + MultisigData: nil, + }, + types.Account{ + Address: address2, + Balance: []types.Balance{ + { + Coin: uint64(types.GetBaseCoinID()), + Value: helpers.StringToBigInt("100000000000000000000").String(), + }, + }, + Nonce: 0, + MultisigData: nil, + }, + types.Account{ + Address: address3, + Balance: []types.Balance{ + { + Coin: uint64(types.GetBaseCoinID()), + Value: helpers.StringToBigInt("100000000000000000000").String(), + }, + }, + Nonce: 0, + MultisigData: nil, + }, + types.Account{ + Address: address4, + Balance: []types.Balance{ + { + Coin: uint64(types.GetBaseCoinID()), + Value: helpers.StringToBigInt("100000000000000000000").String(), + }, + }, + Nonce: 0, + MultisigData: nil, + }, + types.Account{ + Address: address5, + Balance: []types.Balance{ + { + Coin: uint64(types.GetBaseCoinID()), + Value: helpers.StringToBigInt("100000000000000000000").String(), + }, + }, + Nonce: 0, + MultisigData: nil, + }, + types.Account{ + Address: address6, + Balance: []types.Balance{ + { + Coin: uint64(types.GetBaseCoinID()), + Value: helpers.StringToBigInt("100000000000000000000").String(), + }, + }, + Nonce: 0, + MultisigData: nil, + }, + ) + stake := helpers.BipToPip(big.NewInt(10000)).String() + state.Validators = append(state.Validators, + types.Validator{ + TotalBipStake: stake, + PubKey: types.Pubkey{1}, + AccumReward: "10", + AbsentTimes: nil, + }, + types.Validator{ + TotalBipStake: stake, + PubKey: types.Pubkey{2}, + AccumReward: "10", + AbsentTimes: nil, + }, + types.Validator{ + TotalBipStake: stake, + PubKey: types.Pubkey{3}, + AccumReward: "10", + AbsentTimes: nil, + }, + types.Validator{ + TotalBipStake: stake, + PubKey: types.Pubkey{4}, + AccumReward: "10", + AbsentTimes: nil, + }, + types.Validator{ + TotalBipStake: stake, + PubKey: types.Pubkey{5}, + AccumReward: "10", + AbsentTimes: nil, + }, + types.Validator{ + TotalBipStake: stake, + PubKey: types.Pubkey{6}, + AccumReward: "10", + AbsentTimes: nil, + }, + ) + state.Candidates = append(state.Candidates, + types.Candidate{ + ID: 1, + RewardAddress: address1, + OwnerAddress: address1, + ControlAddress: address1, + TotalBipStake: stake, + PubKey: types.Pubkey{1}, + Commission: 10, + Stakes: []types.Stake{ + { + Owner: types.Address{}, + Coin: 0, + Value: stake, + BipValue: stake, + }, + }, + Updates: nil, + Status: 2, + }, + types.Candidate{ + ID: 2, + RewardAddress: address2, + OwnerAddress: address2, + ControlAddress: address2, + TotalBipStake: stake, + PubKey: types.Pubkey{2}, + Commission: 10, + Stakes: []types.Stake{ + { + Owner: types.Address{}, + Coin: 0, + Value: stake, + BipValue: stake, + }, + }, + Updates: nil, + Status: 2, + }, + types.Candidate{ + ID: 3, + RewardAddress: address3, + OwnerAddress: address3, + ControlAddress: address3, + TotalBipStake: stake, + PubKey: types.Pubkey{3}, + Commission: 10, + Stakes: []types.Stake{ + { + Owner: types.Address{}, + Coin: 0, + Value: stake, + BipValue: stake, + }, + }, + Updates: nil, + Status: 2, + }, + types.Candidate{ + ID: 4, + RewardAddress: address4, + OwnerAddress: address4, + ControlAddress: address4, + TotalBipStake: stake, + PubKey: types.Pubkey{4}, + Commission: 10, + Stakes: []types.Stake{ + { + Owner: types.Address{}, + Coin: 0, + Value: stake, + BipValue: stake, + }, + }, + Updates: nil, + Status: 2, + }, + types.Candidate{ + ID: 5, + RewardAddress: address5, + OwnerAddress: address5, + ControlAddress: address5, + TotalBipStake: stake, + PubKey: types.Pubkey{5}, + Commission: 10, + Stakes: []types.Stake{ + { + Owner: types.Address{}, + Coin: 0, + Value: stake, + BipValue: stake, + }, + }, + Updates: nil, + Status: 2, + }, + types.Candidate{ + ID: 6, + RewardAddress: address6, + OwnerAddress: address6, + ControlAddress: address6, + TotalBipStake: stake, + PubKey: types.Pubkey{6}, + Commission: 10, + Stakes: []types.Stake{ + { + Owner: types.Address{}, + Coin: 0, + Value: stake, + BipValue: stake, + }, + }, + Updates: nil, + Status: 2, + }, + ) + app := CreateApp(state) // create application + + SendBeginBlock(app, 1) + { + tx := CreateTx(app, address1, transaction.TypeVoteUpdate, transaction.VoteUpdateData{ + PubKey: types.Pubkey{1}, + Height: 2, + Version: "a", + }) + + response := SendTx(app, SignTx(privateKey1, tx)) // compose and send tx + + // check that result is OK + if response.Code != code.OK { + t.Fatalf("Response code is not OK: %s, %d", response.Log, response.Code) + } + } + { + tx := CreateTx(app, address2, transaction.TypeVoteUpdate, transaction.VoteUpdateData{ + PubKey: types.Pubkey{2}, + Height: 2, + Version: "a", + }) + + response := SendTx(app, SignTx(privateKey2, tx)) // compose and send tx + + // check that result is OK + if response.Code != code.OK { + t.Fatalf("Response code is not OK: %s, %d", response.Log, response.Code) + } + } + { + tx := CreateTx(app, address3, transaction.TypeVoteUpdate, transaction.VoteUpdateData{ + PubKey: types.Pubkey{3}, + Height: 2, + Version: "a", + }) + + response := SendTx(app, SignTx(privateKey3, tx)) // compose and send tx + + // check that result is OK + if response.Code != code.OK { + t.Fatalf("Response code is not OK: %s, %d", response.Log, response.Code) + } + } + { + tx := CreateTx(app, address4, transaction.TypeVoteUpdate, transaction.VoteUpdateData{ + PubKey: types.Pubkey{4}, + Height: 2, + Version: "a", + }) + + response := SendTx(app, SignTx(privateKey4, tx)) // compose and send tx + + // check that result is OK + if response.Code != code.OK { + t.Fatalf("Response code is not OK: %s, %d", response.Log, response.Code) + } + } + { + tx := CreateTx(app, address5, transaction.TypeVoteUpdate, transaction.VoteUpdateData{ + PubKey: types.Pubkey{5}, + Height: 2, + Version: "aA", + }) + + response := SendTx(app, SignTx(privateKey5, tx)) // compose and send tx + + // check that result is OK + if response.Code != code.OK { + t.Fatalf("Response code is not OK: %s, %d", response.Log, response.Code) + } + } + SendEndBlock(app, 1) // send EndBlock + SendCommit(app) // send Commit + + SendBeginBlock(app, 2) + SendEndBlock(app, 2) // send EndBlock + SendCommit(app) // send Commit + + if len(app.UpdateVersions()) != 1 { + t.Fatalf("not updates") + } + + SendBeginBlock(app, 3) // send BeginBlock + { + tx := CreateTx(app, address1, transaction.TypeVoteCommission, transaction.VoteCommissionData{ + PubKey: types.Pubkey{1}, + Coin: types.GetBaseCoinID(), + Height: 5, + Send: big.NewInt(9999), + }) + + response := SendTx(app, SignTx(privateKey1, tx)) // compose and send tx + + // check that result is OK + if response.Code != code.OK { + t.Fatalf("Response code is not OK: %s, %d", response.Log, response.Code) + } + } + { + tx := CreateTx(app, address2, transaction.TypeVoteCommission, transaction.VoteCommissionData{ + PubKey: types.Pubkey{2}, + Coin: types.GetBaseCoinID(), + Height: 5, + Send: big.NewInt(9999), + }) + + response := SendTx(app, SignTx(privateKey2, tx)) // compose and send tx + + // check that result is OK + if response.Code != code.OK { + t.Fatalf("Response code is not OK: %s, %d", response.Log, response.Code) + } + } + { + tx := CreateTx(app, address3, transaction.TypeVoteCommission, transaction.VoteCommissionData{ + PubKey: types.Pubkey{3}, + Coin: types.GetBaseCoinID(), + Height: 5, + Send: big.NewInt(9999), + }) + + response := SendTx(app, SignTx(privateKey3, tx)) // compose and send tx + + // check that result is OK + if response.Code != code.OK { + t.Fatalf("Response code is not OK: %s, %d", response.Log, response.Code) + } + } + SendEndBlock(app, 3) // send EndBlock + SendCommit(app) // send Commit + + SendBeginBlock(app, 4) // send BeginBlock + + { + tx := CreateTx(app, address5, transaction.TypeVoteCommission, transaction.VoteCommissionData{ + PubKey: types.Pubkey{5}, + Coin: types.GetBaseCoinID(), + Height: 5, + Send: big.NewInt(9999), + }) + + response := SendTx(app, SignTx(privateKey5, tx)) // compose and send tx + + // check that result is OK + if response.Code != code.OK { + t.Fatalf("Response code is not OK: %s, %d", response.Log, response.Code) + } + } + { + tx := CreateTx(app, address6, transaction.TypeVoteCommission, transaction.VoteCommissionData{ + PubKey: types.Pubkey{6}, + Coin: types.GetBaseCoinID(), + Height: 5, + Send: big.NewInt(9999), + }) + + response := SendTx(app, SignTx(privateKey6, tx)) // compose and send tx + + // check that result is OK + if response.Code != code.OK { + t.Fatalf("Response code is not OK: %s, %d", response.Log, response.Code) + } + } + + { // Diff + tx := CreateTx(app, address4, transaction.TypeVoteCommission, transaction.VoteCommissionData{ + PubKey: types.Pubkey{4}, + Coin: types.GetBaseCoinID(), + Height: 5, + Send: big.NewInt(2e18), // Diff + }) + + response := SendTx(app, SignTx(privateKey4, tx)) // compose and send tx + + // check that result is OK + if response.Code != code.OK { + t.Fatalf("Response code is not OK: %s, %d", response.Log, response.Code) + } + } + SendEndBlock(app, 4) // send EndBlock + SendCommit(app) // send Commit + + SendBeginBlock(app, 5) + SendEndBlock(app, 5) // send EndBlock + SendCommit(app) // send Commit + + commissions := app.CurrentState().Commission().GetCommissions() + if commissions.Send.Cmp(big.NewInt(9999)) != 0 { + t.Fatalf("comission send is not correct. Expected %s, got %s", big.NewInt(9999), commissions.Send) + } +} From 7b7166522c604a6a1f342af30835a2dec4e6ac91 Mon Sep 17 00:00:00 2001 From: klim0v Date: Fri, 16 Apr 2021 13:41:44 +0300 Subject: [PATCH 05/15] tests --- coreV2/transaction/sell_coin_test.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/coreV2/transaction/sell_coin_test.go b/coreV2/transaction/sell_coin_test.go index bbda9bbd0..5efc89c66 100644 --- a/coreV2/transaction/sell_coin_test.go +++ b/coreV2/transaction/sell_coin_test.go @@ -653,13 +653,15 @@ func TestSellCoinTxCustomToCustomCustom2Commission(t *testing.T) { // check received coins buyCoinBalance := cState.Accounts.GetBalance(addr, coinToBuyID) bipReturn := formula.CalculateSaleReturn(initialVolume1, initialReserve1, crr1, toSell) - estimatedReturn := formula.CalculatePurchaseReturn(initialVolume2, initialReserve2, crr2, bipReturn) + // estimatedReturn := formula.CalculatePurchaseReturn(initialVolume2, initialReserve2, crr2, bipReturn) commissions := cState.Commission.GetCommissions() commissionInBaseCoin := tx.Commission(tx.Price(commissions)) if !commissions.Coin.IsBaseCoin() { commissionInBaseCoin = cState.Swap.GetSwapper(types.GetBaseCoinID(), commissions.Coin).CalculateSellForBuy(commissionInBaseCoin) } - commission := formula.CalculateSaleAmount(big.NewInt(0).Add(initialVolume2, estimatedReturn), big.NewInt(0).Add(initialReserve2, bipReturn), crr2, commissionInBaseCoin) + commission := formula.CalculateSaleAmount(initialVolume2, initialReserve2, crr2, commissionInBaseCoin) + + estimatedReturn := formula.CalculatePurchaseReturn(big.NewInt(0).Sub(initialVolume2, commission), big.NewInt(0).Sub(initialReserve2, commissionInBaseCoin), crr2, bipReturn) estimatedBuyBalance := big.NewInt(0).Set(estimatedReturn) estimatedBuyBalance.Sub(estimatedBuyBalance, commission) @@ -704,7 +706,7 @@ func TestSellCoinTxCustomToCustomCustom2Commission(t *testing.T) { } estimatedSupply := big.NewInt(0).Set(initialVolume2) - estimatedSupply.Add(estimatedSupply, formula.CalculatePurchaseReturn(initialVolume2, initialReserve2, crr2, formula.CalculateSaleReturn(initialVolume1, initialReserve1, crr1, toSell))) + estimatedSupply.Add(estimatedSupply, formula.CalculatePurchaseReturn(big.NewInt(0).Sub(initialVolume2, commission), big.NewInt(0).Sub(initialReserve2, commissionInBaseCoin), crr2, formula.CalculateSaleReturn(initialVolume1, initialReserve1, crr1, toSell))) estimatedSupply.Sub(estimatedSupply, commission) if coinData.Volume().Cmp(estimatedSupply) != 0 { t.Fatalf("Wrong coin supply") From 72a4ba5c83aa0c466f8ade03565707eb6ffd9336 Mon Sep 17 00:00:00 2001 From: klim0v Date: Fri, 16 Apr 2021 14:24:17 +0300 Subject: [PATCH 06/15] refactor --- coreV2/transaction/sell_coin_test.go | 1 - 1 file changed, 1 deletion(-) diff --git a/coreV2/transaction/sell_coin_test.go b/coreV2/transaction/sell_coin_test.go index 5efc89c66..5adaf6778 100644 --- a/coreV2/transaction/sell_coin_test.go +++ b/coreV2/transaction/sell_coin_test.go @@ -653,7 +653,6 @@ func TestSellCoinTxCustomToCustomCustom2Commission(t *testing.T) { // check received coins buyCoinBalance := cState.Accounts.GetBalance(addr, coinToBuyID) bipReturn := formula.CalculateSaleReturn(initialVolume1, initialReserve1, crr1, toSell) - // estimatedReturn := formula.CalculatePurchaseReturn(initialVolume2, initialReserve2, crr2, bipReturn) commissions := cState.Commission.GetCommissions() commissionInBaseCoin := tx.Commission(tx.Price(commissions)) if !commissions.Coin.IsBaseCoin() { From de3e4be94a8e7a6733ca8fd106d586e157a11aa1 Mon Sep 17 00:00:00 2001 From: klim0v Date: Fri, 16 Apr 2021 14:35:47 +0300 Subject: [PATCH 07/15] update version.go --- version/version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version/version.go b/version/version.go index b3b79c623..07c1973d3 100755 --- a/version/version.go +++ b/version/version.go @@ -7,7 +7,7 @@ const ( var ( // Version must be a string because scripts like dist.sh read this file. - Version = "2.0.3" + Version = "2.1.0" // GitCommit is the current HEAD set using ldflags. GitCommit string From de41334f9bef6f296468a3c05de0dbec2cfaa9d8 Mon Sep 17 00:00:00 2001 From: klim0v Date: Fri, 16 Apr 2021 15:58:21 +0300 Subject: [PATCH 08/15] updates --- coreV2/minter/blockchain.go | 48 ++-- tests/votes_test.go | 444 ++++++++++++++++++++++++++++-------- upgrades/blocks.go | 13 -- upgrades/grace.go | 10 + 4 files changed, 389 insertions(+), 126 deletions(-) delete mode 100644 upgrades/blocks.go diff --git a/coreV2/minter/blockchain.go b/coreV2/minter/blockchain.go index b33996ca4..085055a73 100644 --- a/coreV2/minter/blockchain.go +++ b/coreV2/minter/blockchain.go @@ -64,13 +64,14 @@ type Blockchain struct { // currentMempool is responsive for prevent sending multiple transactions from one address in one block currentMempool *sync.Map - lock sync.RWMutex - haltHeight uint64 - cfg *config.Config - storages *utils.Storage - stopChan context.Context - stopped bool - grace *upgrades.Grace + lock sync.RWMutex + haltHeight uint64 + cfg *config.Config + storages *utils.Storage + stopChan context.Context + stopped bool + grace *upgrades.Grace + knownUpdates map[string]struct{} } // NewMinterBlockchain creates Minter Blockchain instance, should be only called once @@ -107,6 +108,12 @@ func NewMinterBlockchain(storages *utils.Storage, cfg *config.Config, ctx contex return app } +func graceForUpdate(height uint64) *upgrades.GracePeriod { + return upgrades.NewGracePeriod(height+1, height+120) +} + +const haltBlockV210 = 3431238 + func (blockchain *Blockchain) initState() { initialHeight := blockchain.appDB.GetStartHeight() currentHeight := blockchain.appDB.GetLastHeight() @@ -126,7 +133,12 @@ func (blockchain *Blockchain) initState() { blockchain.stateCheck = state.NewCheckState(stateDeliver) grace := upgrades.NewGrace() - grace.AddGracePeriods(upgrades.NewGracePeriod(initialHeight, initialHeight+120)) + grace.AddGracePeriods(upgrades.NewGracePeriod(initialHeight, initialHeight+120), + upgrades.NewGracePeriod(haltBlockV210, haltBlockV210+120)) + blockchain.knownUpdates = map[string]struct{}{"": {}} // fill for update + for _, v := range blockchain.UpdateVersions() { + grace.AddGracePeriods(graceForUpdate(v.Height)) + } blockchain.grace = grace } @@ -196,7 +208,11 @@ func (blockchain *Blockchain) BeginBlock(req abciTypes.RequestBeginBlock) abciTy blockchain.calculatePowers(blockchain.stateDeliver.Validators.GetValidators()) - if blockchain.isApplicationHalted(height) { + if blockchain.isApplicationHalted(height) && !blockchain.grace.IsUpgradeBlock(height) { + blockchain.stop() + return abciTypes.ResponseBeginBlock{} + } + if _, ok := blockchain.knownUpdates[blockchain.appDB.GetVersion(height)]; !ok { blockchain.stop() return abciTypes.ResponseBeginBlock{} } @@ -289,11 +305,10 @@ func (blockchain *Blockchain) EndBlock(req abciTypes.RequestEndBlock) abciTypes. if height%blockchain.updateStakesAndPayRewardsPeriod == 0 { blockchain.stateDeliver.Validators.PayRewards() } - currentV := blockchain.appDB.GetVersion(height) { var updateCommissionsBlockPrices []byte - if currentV == "" { + if height < haltBlockV210 { updateCommissionsBlockPrices = blockchain.isUpdateCommissionsBlock(height) } else { updateCommissionsBlockPrices = blockchain.isUpdateCommissionsBlockV2(height) @@ -351,19 +366,12 @@ func (blockchain *Blockchain) EndBlock(req abciTypes.RequestEndBlock) abciTypes. } { - var v string - var ok bool - if currentV == "" { - v, ok = blockchain.isUpdateNetworkBlock(height) - } else { - v, ok = blockchain.isUpdateNetworkBlockV2(height) - } - - if ok { + if v, ok := blockchain.isUpdateNetworkBlockV2(height); ok { blockchain.appDB.AddVersion(v, height) blockchain.eventsDB.AddEvent(&eventsdb.UpdateNetworkEvent{ Version: v, }) + blockchain.grace.AddGracePeriods(graceForUpdate(height)) } blockchain.stateDeliver.Updates.Delete(height) } diff --git a/tests/votes_test.go b/tests/votes_test.go index 9a017df60..65ff3ddd5 100644 --- a/tests/votes_test.go +++ b/tests/votes_test.go @@ -10,6 +10,335 @@ import ( "testing" ) +func TestVoteupdate(t *testing.T) { + privateKey1, _ := crypto.GenerateKey() // create accounts for test + address1 := crypto.PubkeyToAddress(privateKey1.PublicKey) + privateKey2, _ := crypto.GenerateKey() // create accounts for test + address2 := crypto.PubkeyToAddress(privateKey2.PublicKey) + privateKey3, _ := crypto.GenerateKey() // create accounts for test + address3 := crypto.PubkeyToAddress(privateKey3.PublicKey) + privateKey4, _ := crypto.GenerateKey() // create accounts for test + address4 := crypto.PubkeyToAddress(privateKey4.PublicKey) + privateKey5, _ := crypto.GenerateKey() // create accounts for test + address5 := crypto.PubkeyToAddress(privateKey5.PublicKey) + privateKey6, _ := crypto.GenerateKey() // create accounts for test + address6 := crypto.PubkeyToAddress(privateKey6.PublicKey) + + state := DefaultAppState() // generate default state + + // add address to genesis state + state.Accounts = append(state.Accounts, + types.Account{ + Address: address1, + Balance: []types.Balance{ + { + Coin: uint64(types.GetBaseCoinID()), + Value: helpers.StringToBigInt("100000000000000000000").String(), + }, + }, + Nonce: 0, + MultisigData: nil, + }, + types.Account{ + Address: address2, + Balance: []types.Balance{ + { + Coin: uint64(types.GetBaseCoinID()), + Value: helpers.StringToBigInt("100000000000000000000").String(), + }, + }, + Nonce: 0, + MultisigData: nil, + }, + types.Account{ + Address: address3, + Balance: []types.Balance{ + { + Coin: uint64(types.GetBaseCoinID()), + Value: helpers.StringToBigInt("100000000000000000000").String(), + }, + }, + Nonce: 0, + MultisigData: nil, + }, + types.Account{ + Address: address4, + Balance: []types.Balance{ + { + Coin: uint64(types.GetBaseCoinID()), + Value: helpers.StringToBigInt("100000000000000000000").String(), + }, + }, + Nonce: 0, + MultisigData: nil, + }, + types.Account{ + Address: address5, + Balance: []types.Balance{ + { + Coin: uint64(types.GetBaseCoinID()), + Value: helpers.StringToBigInt("100000000000000000000").String(), + }, + }, + Nonce: 0, + MultisigData: nil, + }, + types.Account{ + Address: address6, + Balance: []types.Balance{ + { + Coin: uint64(types.GetBaseCoinID()), + Value: helpers.StringToBigInt("100000000000000000000").String(), + }, + }, + Nonce: 0, + MultisigData: nil, + }, + ) + stake := helpers.BipToPip(big.NewInt(10000)).String() + state.Validators = append(state.Validators, + types.Validator{ + TotalBipStake: stake, + PubKey: types.Pubkey{1}, + AccumReward: "10", + AbsentTimes: nil, + }, + types.Validator{ + TotalBipStake: stake, + PubKey: types.Pubkey{2}, + AccumReward: "10", + AbsentTimes: nil, + }, + types.Validator{ + TotalBipStake: stake, + PubKey: types.Pubkey{3}, + AccumReward: "10", + AbsentTimes: nil, + }, + types.Validator{ + TotalBipStake: stake, + PubKey: types.Pubkey{4}, + AccumReward: "10", + AbsentTimes: nil, + }, + types.Validator{ + TotalBipStake: stake, + PubKey: types.Pubkey{5}, + AccumReward: "10", + AbsentTimes: nil, + }, + types.Validator{ + TotalBipStake: stake, + PubKey: types.Pubkey{6}, + AccumReward: "10", + AbsentTimes: nil, + }, + ) + state.Candidates = append(state.Candidates, + types.Candidate{ + ID: 1, + RewardAddress: address1, + OwnerAddress: address1, + ControlAddress: address1, + TotalBipStake: stake, + PubKey: types.Pubkey{1}, + Commission: 10, + Stakes: []types.Stake{ + { + Owner: types.Address{}, + Coin: 0, + Value: stake, + BipValue: stake, + }, + }, + Updates: nil, + Status: 2, + }, + types.Candidate{ + ID: 2, + RewardAddress: address2, + OwnerAddress: address2, + ControlAddress: address2, + TotalBipStake: stake, + PubKey: types.Pubkey{2}, + Commission: 10, + Stakes: []types.Stake{ + { + Owner: types.Address{}, + Coin: 0, + Value: stake, + BipValue: stake, + }, + }, + Updates: nil, + Status: 2, + }, + types.Candidate{ + ID: 3, + RewardAddress: address3, + OwnerAddress: address3, + ControlAddress: address3, + TotalBipStake: stake, + PubKey: types.Pubkey{3}, + Commission: 10, + Stakes: []types.Stake{ + { + Owner: types.Address{}, + Coin: 0, + Value: stake, + BipValue: stake, + }, + }, + Updates: nil, + Status: 2, + }, + types.Candidate{ + ID: 4, + RewardAddress: address4, + OwnerAddress: address4, + ControlAddress: address4, + TotalBipStake: stake, + PubKey: types.Pubkey{4}, + Commission: 10, + Stakes: []types.Stake{ + { + Owner: types.Address{}, + Coin: 0, + Value: stake, + BipValue: stake, + }, + }, + Updates: nil, + Status: 2, + }, + types.Candidate{ + ID: 5, + RewardAddress: address5, + OwnerAddress: address5, + ControlAddress: address5, + TotalBipStake: stake, + PubKey: types.Pubkey{5}, + Commission: 10, + Stakes: []types.Stake{ + { + Owner: types.Address{}, + Coin: 0, + Value: stake, + BipValue: stake, + }, + }, + Updates: nil, + Status: 2, + }, + types.Candidate{ + ID: 6, + RewardAddress: address6, + OwnerAddress: address6, + ControlAddress: address6, + TotalBipStake: stake, + PubKey: types.Pubkey{6}, + Commission: 10, + Stakes: []types.Stake{ + { + Owner: types.Address{}, + Coin: 0, + Value: stake, + BipValue: stake, + }, + }, + Updates: nil, + Status: 2, + }, + ) + app := CreateApp(state) // create application + + SendBeginBlock(app, 1) + { + tx := CreateTx(app, address1, transaction.TypeVoteUpdate, transaction.VoteUpdateData{ + PubKey: types.Pubkey{1}, + Height: 2, + Version: "a", + }) + + response := SendTx(app, SignTx(privateKey1, tx)) // compose and send tx + + // check that result is OK + if response.Code != code.OK { + t.Fatalf("Response code is not OK: %s, %d", response.Log, response.Code) + } + } + { + tx := CreateTx(app, address2, transaction.TypeVoteUpdate, transaction.VoteUpdateData{ + PubKey: types.Pubkey{2}, + Height: 2, + Version: "a", + }) + + response := SendTx(app, SignTx(privateKey2, tx)) // compose and send tx + + // check that result is OK + if response.Code != code.OK { + t.Fatalf("Response code is not OK: %s, %d", response.Log, response.Code) + } + } + { + tx := CreateTx(app, address3, transaction.TypeVoteUpdate, transaction.VoteUpdateData{ + PubKey: types.Pubkey{3}, + Height: 2, + Version: "a", + }) + + response := SendTx(app, SignTx(privateKey3, tx)) // compose and send tx + + // check that result is OK + if response.Code != code.OK { + t.Fatalf("Response code is not OK: %s, %d", response.Log, response.Code) + } + } + { + tx := CreateTx(app, address4, transaction.TypeVoteUpdate, transaction.VoteUpdateData{ + PubKey: types.Pubkey{4}, + Height: 2, + Version: "a", + }) + + response := SendTx(app, SignTx(privateKey4, tx)) // compose and send tx + + // check that result is OK + if response.Code != code.OK { + t.Fatalf("Response code is not OK: %s, %d", response.Log, response.Code) + } + } + { + tx := CreateTx(app, address5, transaction.TypeVoteUpdate, transaction.VoteUpdateData{ + PubKey: types.Pubkey{5}, + Height: 2, + Version: "aA", + }) + + response := SendTx(app, SignTx(privateKey5, tx)) // compose and send tx + + // check that result is OK + if response.Code != code.OK { + t.Fatalf("Response code is not OK: %s, %d", response.Log, response.Code) + } + } + SendEndBlock(app, 1) // send EndBlock + SendCommit(app) // send Commit + + SendBeginBlock(app, 2) + SendEndBlock(app, 2) // send EndBlock + SendCommit(app) // send Commit + + if len(app.UpdateVersions()) != 1 { + t.Fatalf("not updates") + } + + if app.UpdateVersions()[0].Name != "a" { + t.Fatalf("error update") + } +} + func TestVoteCommissionFail(t *testing.T) { privateKey1, _ := crypto.GenerateKey() // create accounts for test address1 := crypto.PubkeyToAddress(privateKey1.PublicKey) @@ -612,94 +941,23 @@ func TestVoteCommissionOKUpdateVersion(t *testing.T) { ) app := CreateApp(state) // create application - SendBeginBlock(app, 1) - { - tx := CreateTx(app, address1, transaction.TypeVoteUpdate, transaction.VoteUpdateData{ - PubKey: types.Pubkey{1}, - Height: 2, - Version: "a", - }) - - response := SendTx(app, SignTx(privateKey1, tx)) // compose and send tx - - // check that result is OK - if response.Code != code.OK { - t.Fatalf("Response code is not OK: %s, %d", response.Log, response.Code) - } - } - { - tx := CreateTx(app, address2, transaction.TypeVoteUpdate, transaction.VoteUpdateData{ - PubKey: types.Pubkey{2}, - Height: 2, - Version: "a", - }) - - response := SendTx(app, SignTx(privateKey2, tx)) // compose and send tx - - // check that result is OK - if response.Code != code.OK { - t.Fatalf("Response code is not OK: %s, %d", response.Log, response.Code) - } - } - { - tx := CreateTx(app, address3, transaction.TypeVoteUpdate, transaction.VoteUpdateData{ - PubKey: types.Pubkey{3}, - Height: 2, - Version: "a", - }) - - response := SendTx(app, SignTx(privateKey3, tx)) // compose and send tx - - // check that result is OK - if response.Code != code.OK { - t.Fatalf("Response code is not OK: %s, %d", response.Log, response.Code) - } - } - { - tx := CreateTx(app, address4, transaction.TypeVoteUpdate, transaction.VoteUpdateData{ - PubKey: types.Pubkey{4}, - Height: 2, - Version: "a", - }) - - response := SendTx(app, SignTx(privateKey4, tx)) // compose and send tx - - // check that result is OK - if response.Code != code.OK { - t.Fatalf("Response code is not OK: %s, %d", response.Log, response.Code) - } - } - { - tx := CreateTx(app, address5, transaction.TypeVoteUpdate, transaction.VoteUpdateData{ - PubKey: types.Pubkey{5}, - Height: 2, - Version: "aA", - }) - - response := SendTx(app, SignTx(privateKey5, tx)) // compose and send tx + const haltBlockV210 = 3431238 - // check that result is OK - if response.Code != code.OK { - t.Fatalf("Response code is not OK: %s, %d", response.Log, response.Code) - } - } - SendEndBlock(app, 1) // send EndBlock - SendCommit(app) // send Commit + SendBeginBlock(app, haltBlockV210) - SendBeginBlock(app, 2) - SendEndBlock(app, 2) // send EndBlock - SendCommit(app) // send Commit + SendEndBlock(app, haltBlockV210) // send EndBlock + SendCommit(app) // send Commit - if len(app.UpdateVersions()) != 1 { - t.Fatalf("not updates") - } + SendBeginBlock(app, haltBlockV210+1) + SendEndBlock(app, haltBlockV210+1) // send EndBlock + SendCommit(app) // send Commit - SendBeginBlock(app, 3) // send BeginBlock + SendBeginBlock(app, haltBlockV210+2) // send BeginBlock { tx := CreateTx(app, address1, transaction.TypeVoteCommission, transaction.VoteCommissionData{ PubKey: types.Pubkey{1}, Coin: types.GetBaseCoinID(), - Height: 5, + Height: haltBlockV210 + 4, Send: big.NewInt(9999), }) @@ -714,7 +972,7 @@ func TestVoteCommissionOKUpdateVersion(t *testing.T) { tx := CreateTx(app, address2, transaction.TypeVoteCommission, transaction.VoteCommissionData{ PubKey: types.Pubkey{2}, Coin: types.GetBaseCoinID(), - Height: 5, + Height: haltBlockV210 + 4, Send: big.NewInt(9999), }) @@ -729,7 +987,7 @@ func TestVoteCommissionOKUpdateVersion(t *testing.T) { tx := CreateTx(app, address3, transaction.TypeVoteCommission, transaction.VoteCommissionData{ PubKey: types.Pubkey{3}, Coin: types.GetBaseCoinID(), - Height: 5, + Height: haltBlockV210 + 4, Send: big.NewInt(9999), }) @@ -740,16 +998,16 @@ func TestVoteCommissionOKUpdateVersion(t *testing.T) { t.Fatalf("Response code is not OK: %s, %d", response.Log, response.Code) } } - SendEndBlock(app, 3) // send EndBlock - SendCommit(app) // send Commit + SendEndBlock(app, haltBlockV210+2) // send EndBlock + SendCommit(app) // send Commit - SendBeginBlock(app, 4) // send BeginBlock + SendBeginBlock(app, haltBlockV210+3) // send BeginBlock { tx := CreateTx(app, address5, transaction.TypeVoteCommission, transaction.VoteCommissionData{ PubKey: types.Pubkey{5}, Coin: types.GetBaseCoinID(), - Height: 5, + Height: haltBlockV210 + 4, Send: big.NewInt(9999), }) @@ -764,7 +1022,7 @@ func TestVoteCommissionOKUpdateVersion(t *testing.T) { tx := CreateTx(app, address6, transaction.TypeVoteCommission, transaction.VoteCommissionData{ PubKey: types.Pubkey{6}, Coin: types.GetBaseCoinID(), - Height: 5, + Height: haltBlockV210 + 4, Send: big.NewInt(9999), }) @@ -780,7 +1038,7 @@ func TestVoteCommissionOKUpdateVersion(t *testing.T) { tx := CreateTx(app, address4, transaction.TypeVoteCommission, transaction.VoteCommissionData{ PubKey: types.Pubkey{4}, Coin: types.GetBaseCoinID(), - Height: 5, + Height: haltBlockV210 + 4, Send: big.NewInt(2e18), // Diff }) @@ -791,12 +1049,12 @@ func TestVoteCommissionOKUpdateVersion(t *testing.T) { t.Fatalf("Response code is not OK: %s, %d", response.Log, response.Code) } } - SendEndBlock(app, 4) // send EndBlock - SendCommit(app) // send Commit + SendEndBlock(app, haltBlockV210+3) // send EndBlock + SendCommit(app) // send Commit - SendBeginBlock(app, 5) - SendEndBlock(app, 5) // send EndBlock - SendCommit(app) // send Commit + SendBeginBlock(app, haltBlockV210+4) + SendEndBlock(app, haltBlockV210+4) // send EndBlock + SendCommit(app) // send Commit commissions := app.CurrentState().Commission().GetCommissions() if commissions.Send.Cmp(big.NewInt(9999)) != 0 { diff --git a/upgrades/blocks.go b/upgrades/blocks.go deleted file mode 100644 index cebe7a27a..000000000 --- a/upgrades/blocks.go +++ /dev/null @@ -1,13 +0,0 @@ -package upgrades - -// func IsUpgradeBlock(height uint64) bool { -// upgradeBlocks := []uint64{} // fill this -// -// for _, block := range upgradeBlocks { -// if height == block { -// return true -// } -// } -// -// return false -// } diff --git a/upgrades/grace.go b/upgrades/grace.go index 2ea5c0970..fe0e90ce3 100644 --- a/upgrades/grace.go +++ b/upgrades/grace.go @@ -4,6 +4,16 @@ type Grace struct { gracePeriods []*GracePeriod } +func (g *Grace) IsUpgradeBlock(height uint64) bool { + for _, period := range g.gracePeriods { + if height == period.from { + return true + } + } + + return false +} + func (g *Grace) AddGracePeriods(gracePeriods ...*GracePeriod) { g.gracePeriods = append(g.gracePeriods, gracePeriods...) } From 345a4199b428364ddc99affed71dd385bf7b914c Mon Sep 17 00:00:00 2001 From: klim0v Date: Fri, 16 Apr 2021 16:08:20 +0300 Subject: [PATCH 09/15] updates --- coreV2/minter/blockchain.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coreV2/minter/blockchain.go b/coreV2/minter/blockchain.go index 085055a73..fef782a5a 100644 --- a/coreV2/minter/blockchain.go +++ b/coreV2/minter/blockchain.go @@ -109,7 +109,7 @@ func NewMinterBlockchain(storages *utils.Storage, cfg *config.Config, ctx contex } func graceForUpdate(height uint64) *upgrades.GracePeriod { - return upgrades.NewGracePeriod(height+1, height+120) + return upgrades.NewGracePeriod(height, height+120) } const haltBlockV210 = 3431238 From c70ba145aeb0914a643d39b2a6a9fb90eb26ef62 Mon Sep 17 00:00:00 2001 From: klim0v Date: Fri, 16 Apr 2021 16:21:44 +0300 Subject: [PATCH 10/15] updates --- coreV2/appdb/appdb.go | 16 +++++++++++++++- coreV2/minter/blockchain.go | 2 +- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/coreV2/appdb/appdb.go b/coreV2/appdb/appdb.go index ff4dd3088..92c25477b 100644 --- a/coreV2/appdb/appdb.go +++ b/coreV2/appdb/appdb.go @@ -248,7 +248,7 @@ type Version struct { Height uint64 } -func (appDB *AppDB) GetVersion(height uint64) string { +func (appDB *AppDB) GetVersionName(height uint64) string { appDB.GetVersions() lastVersionName := "" @@ -262,6 +262,20 @@ func (appDB *AppDB) GetVersion(height uint64) string { return lastVersionName } +func (appDB *AppDB) GetVersionHeight(name string) uint64 { + appDB.GetVersions() + + var lastVersionHeight uint64 + for _, version := range appDB.versions { + if version.Name == name { + return lastVersionHeight + } + lastVersionHeight = version.Height + } + + return lastVersionHeight +} + func (appDB *AppDB) GetVersions() []*Version { if len(appDB.versions) == 0 { result, err := appDB.db.Get([]byte(versionsPath)) diff --git a/coreV2/minter/blockchain.go b/coreV2/minter/blockchain.go index fef782a5a..bdab7cdc3 100644 --- a/coreV2/minter/blockchain.go +++ b/coreV2/minter/blockchain.go @@ -212,7 +212,7 @@ func (blockchain *Blockchain) BeginBlock(req abciTypes.RequestBeginBlock) abciTy blockchain.stop() return abciTypes.ResponseBeginBlock{} } - if _, ok := blockchain.knownUpdates[blockchain.appDB.GetVersion(height)]; !ok { + if _, ok := blockchain.knownUpdates[blockchain.appDB.GetVersionName(height)]; !ok { blockchain.stop() return abciTypes.ResponseBeginBlock{} } From 49b747c1f9322d8bd478485935776934c07db7aa Mon Sep 17 00:00:00 2001 From: klim0v Date: Fri, 16 Apr 2021 16:25:56 +0300 Subject: [PATCH 11/15] updates --- coreV2/minter/blockchain.go | 5 ++++- coreV2/minter/minter.go | 34 ---------------------------------- 2 files changed, 4 insertions(+), 35 deletions(-) diff --git a/coreV2/minter/blockchain.go b/coreV2/minter/blockchain.go index bdab7cdc3..037732a94 100644 --- a/coreV2/minter/blockchain.go +++ b/coreV2/minter/blockchain.go @@ -135,7 +135,10 @@ func (blockchain *Blockchain) initState() { grace := upgrades.NewGrace() grace.AddGracePeriods(upgrades.NewGracePeriod(initialHeight, initialHeight+120), upgrades.NewGracePeriod(haltBlockV210, haltBlockV210+120)) - blockchain.knownUpdates = map[string]struct{}{"": {}} // fill for update + blockchain.knownUpdates = map[string]struct{}{ + "": {}, // default version + // add more for update + } for _, v := range blockchain.UpdateVersions() { grace.AddGracePeriods(graceForUpdate(v.Height)) } diff --git a/coreV2/minter/minter.go b/coreV2/minter/minter.go index 9deaecac8..60d3b4af4 100644 --- a/coreV2/minter/minter.go +++ b/coreV2/minter/minter.go @@ -360,40 +360,6 @@ func (blockchain *Blockchain) isUpdateCommissionsBlockV2(height uint64) []byte { return nil } -// Deprecated -func (blockchain *Blockchain) isUpdateNetworkBlock(height uint64) (string, bool) { - versions := blockchain.stateDeliver.Updates.GetVotes(height) - if len(versions) == 0 { - return "", false - } - // calculate total power of validators - maxVotingResult := big.NewFloat(0) - totalVotedPower := big.NewInt(0) - - var version string - for _, v := range versions { - for _, vote := range v.Votes { - if power, ok := blockchain.validatorsPowers[vote]; ok { - totalVotedPower.Add(totalVotedPower, power) - } - } - votingResult := new(big.Float).Quo( - new(big.Float).SetInt(totalVotedPower), - new(big.Float).SetInt(blockchain.totalPower), - ) - - if maxVotingResult.Cmp(votingResult) == -1 { - maxVotingResult = votingResult - version = v.Version - } - } - if maxVotingResult.Cmp(big.NewFloat(votingPowerConsensus)) == 1 { - return version, true - } - - return "", false -} - func (blockchain *Blockchain) isUpdateNetworkBlockV2(height uint64) (string, bool) { versions := blockchain.stateDeliver.Updates.GetVotes(height) if len(versions) == 0 { From 26658bdf45a0486104f082a749d4a9b171a6631d Mon Sep 17 00:00:00 2001 From: klim0v Date: Fri, 16 Apr 2021 18:08:09 +0300 Subject: [PATCH 12/15] review --- .github/workflows/main.yml | 10 ++++++++-- coreV2/appdb/appdb.go | 8 ++------ coreV2/minter/blockchain.go | 8 +++++++- 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index e7666638c..174932e3c 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -14,7 +14,7 @@ jobs: env: CONTAINER_NAME: minter_node CONTAINER_TIMEOUT_SEC: 30 - API_RUN_PORT: 8841 + API_RUN_PORT: 8843 SECRET_DOCKER_HUB_PASSWORD: ${{ secrets.DOCKER_HUB_PASSWORD }} SECRET_DOCKER_HUB_USER: ${{ secrets.DOCKER_HUB_USER }} SECRET_DOCKER_HUB_REPO: ${{ secrets.DOCKER_HUB_REPO }} @@ -29,6 +29,8 @@ jobs: # if secret DOCKER_HUB_REPO is not set DOCKER_HUB_USER will be used instead of REPO # otherwise secrets are empty and repo "testbuild" will be used - name: Set envs + env: + ACTIONS_ALLOW_UNSECURE_COMMANDS: 'true' run: | echo ::set-env name=VERSION::$(awk -F\" '/Version =/ { print $2; exit }' < version/version.go) echo ::set-env name=DOCKER_REPO::$(if [[ "$SECRET_DOCKER_HUB_REPO" == "" ]]; then if [[ "$SECRET_DOCKER_HUB_USER" == "" ]]; then echo "testbuild"; else echo "$SECRET_DOCKER_HUB_USER"; fi; else echo "$SECRET_DOCKER_HUB_REPO"; fi) @@ -37,13 +39,17 @@ jobs: run: docker build -t $DOCKER_REPO/$DOCKER_IMAGE:$VERSION . -f ./Dockerfile-ci - name: Start docker container - run: docker run -d --name $CONTAINER_NAME -p $API_RUN_PORT:8841 $DOCKER_REPO/$DOCKER_IMAGE:$VERSION + run: docker run -d --name $CONTAINER_NAME -p $API_RUN_PORT:8843 $DOCKER_REPO/$DOCKER_IMAGE:$VERSION - name: Check container is still running + env: + ACTIONS_ALLOW_UNSECURE_COMMANDS: 'true' run: | echo ::set-env name=RUN_TEST_RESULT::$(sleep $CONTAINER_TIMEOUT_SEC && if [[ $(docker inspect -f "{{.State.Running}}" $CONTAINER_NAME 2> /dev/null) == true ]]; then echo OK; else echo FAIL; fi) - name: Check api is available by HTTP (response code is 200) + env: + ACTIONS_ALLOW_UNSECURE_COMMANDS: 'true' run: | echo ::set-env name=API_TEST_RESULT::$(if [[ $(curl -LIs localhost:$API_RUN_PORT -o /dev/null -w '%{http_code}') == 200 ]]; then echo OK; else echo FAIL; fi) diff --git a/coreV2/appdb/appdb.go b/coreV2/appdb/appdb.go index 92c25477b..2e257693a 100644 --- a/coreV2/appdb/appdb.go +++ b/coreV2/appdb/appdb.go @@ -249,10 +249,8 @@ type Version struct { } func (appDB *AppDB) GetVersionName(height uint64) string { - appDB.GetVersions() - lastVersionName := "" - for _, version := range appDB.versions { + for _, version := range appDB.GetVersions() { if version.Height > height { return lastVersionName } @@ -263,10 +261,8 @@ func (appDB *AppDB) GetVersionName(height uint64) string { } func (appDB *AppDB) GetVersionHeight(name string) uint64 { - appDB.GetVersions() - var lastVersionHeight uint64 - for _, version := range appDB.versions { + for _, version := range appDB.GetVersions() { if version.Name == name { return lastVersionHeight } diff --git a/coreV2/minter/blockchain.go b/coreV2/minter/blockchain.go index 037732a94..f92d3a942 100644 --- a/coreV2/minter/blockchain.go +++ b/coreV2/minter/blockchain.go @@ -2,6 +2,7 @@ package minter import ( "context" + "fmt" "github.com/MinterTeam/minter-go-node/cmd/utils" "github.com/MinterTeam/minter-go-node/config" "github.com/MinterTeam/minter-go-node/coreV2/appdb" @@ -18,6 +19,7 @@ import ( tmjson "github.com/tendermint/tendermint/libs/json" tmNode "github.com/tendermint/tendermint/node" rpc "github.com/tendermint/tendermint/rpc/client/local" + "log" "math/big" "sync" "sync/atomic" @@ -212,10 +214,14 @@ func (blockchain *Blockchain) BeginBlock(req abciTypes.RequestBeginBlock) abciTy blockchain.calculatePowers(blockchain.stateDeliver.Validators.GetValidators()) if blockchain.isApplicationHalted(height) && !blockchain.grace.IsUpgradeBlock(height) { + fmt.Printf("Application halted at height %d", height) blockchain.stop() return abciTypes.ResponseBeginBlock{} } - if _, ok := blockchain.knownUpdates[blockchain.appDB.GetVersionName(height)]; !ok { + + versionName := blockchain.appDB.GetVersionName(height) + if _, ok := blockchain.knownUpdates[versionName]; !ok { + log.Printf("Update your node binary to the latest version: %s", versionName) blockchain.stop() return abciTypes.ResponseBeginBlock{} } From 26740019afdcc06e8f9a581e9e367562d59596f8 Mon Sep 17 00:00:00 2001 From: klim0v Date: Fri, 16 Apr 2021 18:12:55 +0300 Subject: [PATCH 13/15] refactor --- coreV2/minter/blockchain.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/coreV2/minter/blockchain.go b/coreV2/minter/blockchain.go index f92d3a942..9f366cb3e 100644 --- a/coreV2/minter/blockchain.go +++ b/coreV2/minter/blockchain.go @@ -2,7 +2,6 @@ package minter import ( "context" - "fmt" "github.com/MinterTeam/minter-go-node/cmd/utils" "github.com/MinterTeam/minter-go-node/config" "github.com/MinterTeam/minter-go-node/coreV2/appdb" @@ -214,7 +213,7 @@ func (blockchain *Blockchain) BeginBlock(req abciTypes.RequestBeginBlock) abciTy blockchain.calculatePowers(blockchain.stateDeliver.Validators.GetValidators()) if blockchain.isApplicationHalted(height) && !blockchain.grace.IsUpgradeBlock(height) { - fmt.Printf("Application halted at height %d", height) + log.Printf("Application halted at height %d\n", height) blockchain.stop() return abciTypes.ResponseBeginBlock{} } From bd1e36554dcb633d6b45a5fe696d93dfeebcb400 Mon Sep 17 00:00:00 2001 From: klim0v Date: Fri, 16 Apr 2021 18:13:22 +0300 Subject: [PATCH 14/15] ci --- .github/workflows/main.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 174932e3c..b9697a8c3 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -8,6 +8,7 @@ on: pull_request: branches: - master + - dev jobs: docker: From a4e3a343661b197c15776c59b017c771f7f9158e Mon Sep 17 00:00:00 2001 From: klim0v Date: Fri, 16 Apr 2021 18:14:05 +0300 Subject: [PATCH 15/15] ci --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index b9697a8c3..8034c1d65 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -4,11 +4,11 @@ on: push: branches: - master + - dev pull_request: branches: - master - - dev jobs: docker: