From 1e5d9dd55d656f0696cc503dde657c270c18e6a5 Mon Sep 17 00:00:00 2001 From: Bernardo Ramos Date: Thu, 14 Sep 2023 23:04:58 -0300 Subject: [PATCH 01/22] params: move functions to param.go, fix others --- contract/system/param.go | 27 ++++++++++++++++++++++----- contract/system/vote.go | 23 ----------------------- 2 files changed, 22 insertions(+), 28 deletions(-) diff --git a/contract/system/param.go b/contract/system/param.go index a4fe2ba1a..40c75687d 100644 --- a/contract/system/param.go +++ b/contract/system/param.go @@ -38,14 +38,23 @@ var ( func InitSystemParams(g dataGetter, bpCount int) { initDefaultBpCount(bpCount) - systemParams = loadParam(g) + systemParams = loadParams(g) +} + +// Caution: This function must be called only once before all the aergosvr +// services start. +func initDefaultBpCount(count int) { + // Ensure that it is not modified after it is initialized. + if DefaultParams[bpCount.ID()] == nil { + DefaultParams[bpCount.ID()] = big.NewInt(int64(count)) + } } func genParamKey(id string) []byte { return []byte("param\\" + strings.ToUpper(id)) } -func loadParam(g dataGetter) parameters { +func loadParams(g dataGetter) parameters { ret := map[string]*big.Int{} for i := sysParamIndex(0); i < sysParamMax; i++ { id := i.ID() @@ -53,11 +62,11 @@ func loadParam(g dataGetter) parameters { if err != nil { panic("could not load blockchain parameter") } - if data == nil { + if data != nil { + ret[id] = new(big.Int).SetBytes(data) + } else { ret[id] = DefaultParams[id] - continue } - ret[id] = new(big.Int).SetBytes(data) } return ret } @@ -94,6 +103,10 @@ func GetNamePrice() *big.Int { return GetParam(namePrice.ID()) } +func GetBpCount() int { + return int(GetParam(bpCount.ID()).Uint64()) +} + func GetNamePriceFromState(scs *state.ContractState) *big.Int { return getParamFromState(scs, namePrice) } @@ -110,6 +123,10 @@ func GetGasPriceFromState(ar AccountStateReader) *big.Int { return getParamFromState(scs, gasPrice) } +func GetParam(proposalID string) *big.Int { + return systemParams.getLastParam(proposalID) +} + func getParamFromState(scs *state.ContractState, id sysParamIndex) *big.Int { data, err := scs.GetInitialData(genParamKey(id.ID())) if err != nil { diff --git a/contract/system/vote.go b/contract/system/vote.go index 5d2ee9187..bcdaeea6e 100644 --- a/contract/system/vote.go +++ b/contract/system/vote.go @@ -27,8 +27,6 @@ const ( var ( votingCatalog []types.VotingIssue - lastBpCount int - voteKey = []byte("vote") totalKey = []byte("total") sortKey = []byte("sort") @@ -94,7 +92,6 @@ func (c *vprCmd) subVote(v *types.Vote) error { votingPowerRank.sub(c.Sender.AccountID(), c.Sender.ID(), v.GetAmountBigInt()) // Hotfix - reproduce vpr calculation for block 138015125 // When block is reverted, votingPowerRank is not reverted and calculated three times. - // TODO : implement commit, revert, reorg for governance variables. if c.BlockInfo.No == 138015125 && c.Sender.AccountID().String() == "36t2u7Q31HmEbkkYZng7DHNm3xepxHKUfgGrAXNA8pMW" { for i := 0; i < 2; i++ { votingPowerRank.sub(c.Sender.AccountID(), c.Sender.ID(), v.GetAmountBigInt()) @@ -107,7 +104,6 @@ func (c *vprCmd) addVote(v *types.Vote) error { votingPowerRank.add(c.Sender.AccountID(), c.Sender.ID(), v.GetAmountBigInt()) // Hotfix - reproduce vpr calculation for block 138015125 // When block is reverted, votingPowerRank is not reverted and calculated three times. - // TODO : implement commit, revert, reorg for governance variables. if c.BlockInfo.No == 138015125 && c.Sender.AccountID().String() == "36t2u7Q31HmEbkkYZng7DHNm3xepxHKUfgGrAXNA8pMW" { for i := 0; i < 2; i++ { votingPowerRank.add(c.Sender.AccountID(), c.Sender.ID(), v.GetAmountBigInt()) @@ -359,21 +355,6 @@ func GetVoteResult(ar AccountStateReader, id []byte, n int) (*types.VoteList, er return getVoteResult(scs, id, n) } -// initDefaultBpCount sets lastBpCount to bpCount. -// -// Caution: This function must be called only once before all the aergosvr -// services start. -func initDefaultBpCount(count int) { - // Ensure that it is not modified after it is initialized. - if DefaultParams[bpCount.ID()] == nil { - DefaultParams[bpCount.ID()] = big.NewInt(int64(count)) - } -} - -func GetBpCount() int { - return int(GetParam(bpCount.ID()).Uint64()) -} - // GetRankers returns the IDs of the top n rankers. func GetRankers(ar AccountStateReader) ([]string, error) { n := GetBpCount() @@ -390,10 +371,6 @@ func GetRankers(ar AccountStateReader) ([]string, error) { return bps, nil } -func GetParam(proposalID string) *big.Int { - return systemParams.getLastParam(proposalID) -} - func serializeVoteList(vl *types.VoteList, ex bool) []byte { var data []byte for _, v := range vl.GetVotes() { From d7355f30c8bf44c5a7f49e94b5ea19380482e27c Mon Sep 17 00:00:00 2001 From: Bernardo Ramos Date: Fri, 15 Sep 2023 01:09:10 -0300 Subject: [PATCH 02/22] make param active on the next block --- consensus/impl/dpos/status.go | 7 ++++ contract/system/param.go | 70 ++++++++++++++++++++++++----------- contract/system/voteresult.go | 2 +- 3 files changed, 57 insertions(+), 22 deletions(-) diff --git a/consensus/impl/dpos/status.go b/consensus/impl/dpos/status.go index 8fa303a02..f4f88be32 100644 --- a/consensus/impl/dpos/status.go +++ b/consensus/impl/dpos/status.go @@ -83,6 +83,10 @@ func (s *Status) Update(block *types.Block) { } bps, _ = s.bps.AddSnapshot(block.BlockNo()) + + // if a system param was changed, apply its new value + system.CommitParams(true) + } else { // Rollback resulting from a reorganization: The code below assumes // that there is no block-by-block rollback; it assumes that the @@ -109,6 +113,9 @@ func (s *Status) Update(block *types.Block) { } else { logger.Debug().Uint64("from block no", block.BlockNo()).Msg("VPR reloaded") } + + // if a system param was changed, discard its new value + system.CommitParams(false) } s.libState.gc(bps) diff --git a/contract/system/param.go b/contract/system/param.go index 40c75687d..d8f87ae45 100644 --- a/contract/system/param.go +++ b/contract/system/param.go @@ -36,12 +36,16 @@ var ( } ) +func genParamKey(id string) []byte { + return []byte("param\\" + strings.ToUpper(id)) +} + func InitSystemParams(g dataGetter, bpCount int) { initDefaultBpCount(bpCount) systemParams = loadParams(g) } -// Caution: This function must be called only once before all the aergosvr +// This function must be called before all the aergosvr // services start. func initDefaultBpCount(count int) { // Ensure that it is not modified after it is initialized. @@ -50,10 +54,7 @@ func initDefaultBpCount(count int) { } } -func genParamKey(id string) []byte { - return []byte("param\\" + strings.ToUpper(id)) -} - +// load the params from the database or use the default values func loadParams(g dataGetter) parameters { ret := map[string]*big.Int{} for i := sysParamIndex(0); i < sysParamMax; i++ { @@ -71,26 +72,55 @@ func loadParams(g dataGetter) parameters { return ret } -func (p parameters) getLastParam(proposalID string) *big.Int { - if val, ok := p[proposalID]; ok { - return val +func updateParam(s dataSetter, id string, value *big.Int) (error) { + // save the param to the database (in a db txn, commit when the block is connected) + if err := s.SetData(genParamKey(id), value.Bytes()); err != nil { + return err } - return DefaultParams[proposalID] + // save the new value for the param, only active on the next block + systemParams.setNextParam(id, value) + return nil } -func (p parameters) setLastParam(proposalID string, value *big.Int) *big.Int { - p[proposalID] = value - return value +// save the new value for the param, to be active on the next block +func (p parameters) setNextParam(proposalID string, value *big.Int) { + p[proposalID + "next"] = value } -func updateParam(s dataSetter, id string, value *big.Int) (*big.Int, error) { - if err := s.SetData(genParamKey(id), value.Bytes()); err != nil { - return nil, err +// if a system param was changed, apply or discard its new value +func (p parameters) CommitParams(success bool) { + for i := sysParamIndex(0); i < sysParamMax; i++ { + id := i.ID() + if p[id + "next"] != nil { + if success { + p[id] = p[id + "next"] + } + p[id + "next"] = nil + } } - ret := systemParams.setLastParam(id, value) - return ret, nil } +// get the param value for the next block +func GetNextParam(proposalID string) *big.Int { + if val, ok := systemParams[proposalID + "next"]; ok { + return val + } + if val, ok := systemParams[proposalID]; ok { + return val + } + return DefaultParams[proposalID] +} + +// get the param value for the current block +func GetParam(proposalID string) *big.Int { + if val, ok := systemParams[proposalID]; ok { + return val + } + return DefaultParams[proposalID] +} + +// these 4 functions are reading the param value for the current block + func GetStakingMinimum() *big.Int { return GetParam(stakingMin.ID()) } @@ -107,6 +137,8 @@ func GetBpCount() int { return int(GetParam(bpCount.ID()).Uint64()) } +// these functions are reading the param value directly from the state + func GetNamePriceFromState(scs *state.ContractState) *big.Int { return getParamFromState(scs, namePrice) } @@ -123,10 +155,6 @@ func GetGasPriceFromState(ar AccountStateReader) *big.Int { return getParamFromState(scs, gasPrice) } -func GetParam(proposalID string) *big.Int { - return systemParams.getLastParam(proposalID) -} - func getParamFromState(scs *state.ContractState, id sysParamIndex) *big.Int { data, err := scs.GetInitialData(genParamKey(id.ID())) if err != nil { diff --git a/contract/system/voteresult.go b/contract/system/voteresult.go index 33d9aded0..53656739d 100644 --- a/contract/system/voteresult.go +++ b/contract/system/voteresult.go @@ -117,7 +117,7 @@ func (vr *VoteResult) Sync() error { if !ok { return fmt.Errorf("abnormal winner is in vote %s", string(vr.key)) } - if _, err := updateParam(vr.scs, string(vr.key), value); err != nil { + if err := updateParam(vr.scs, string(vr.key), value); err != nil { return err } } From d8115be82b6f1586a48709584287566d6713b744 Mon Sep 17 00:00:00 2001 From: Bernardo Ramos Date: Fri, 15 Sep 2023 01:23:30 -0300 Subject: [PATCH 03/22] read param from memory instead of from state --- chain/chainhandle.go | 2 +- consensus/impl/dpos/blockfactory.go | 2 +- consensus/impl/dpos/status.go | 1 + consensus/impl/raftv2/blockfactory.go | 2 +- consensus/impl/sbp/sbp.go | 2 +- contract/name/execute.go | 4 ++-- contract/system/validation.go | 4 ++-- 7 files changed, 9 insertions(+), 8 deletions(-) diff --git a/chain/chainhandle.go b/chain/chainhandle.go index 14be24121..56691e49b 100644 --- a/chain/chainhandle.go +++ b/chain/chainhandle.go @@ -601,7 +601,7 @@ func newBlockExecutor(cs *ChainService, bState *state.BlockState, block *types.B // executed by the block factory. commitOnly = true } - bState.SetGasPrice(system.GetGasPriceFromState(bState)) + bState.SetGasPrice(system.GetGasPrice()) bState.Receipts().SetHardFork(cs.cfg.Hardfork, block.BlockNo()) return &blockExecutor{ diff --git a/consensus/impl/dpos/blockfactory.go b/consensus/impl/dpos/blockfactory.go index 10dfb9d41..d2b4d3d22 100644 --- a/consensus/impl/dpos/blockfactory.go +++ b/consensus/impl/dpos/blockfactory.go @@ -232,7 +232,7 @@ func (bf *BlockFactory) generateBlock(bpi *bpInfo, lpbNo types.BlockNo) (block * bpi.bestBlock.GetHeader().GetBlocksRootHash(), state.SetPrevBlockHash(bpi.bestBlock.BlockHash()), ) - bs.SetGasPrice(system.GetGasPriceFromState(bs)) + bs.SetGasPrice(system.GetGasPrice()) bs.Receipts().SetHardFork(bf.bv, bi.No) bGen := chain.NewBlockGenerator( diff --git a/consensus/impl/dpos/status.go b/consensus/impl/dpos/status.go index f4f88be32..85ccd9ed9 100644 --- a/consensus/impl/dpos/status.go +++ b/consensus/impl/dpos/status.go @@ -6,6 +6,7 @@ import ( "github.com/aergoio/aergo/v2/consensus" "github.com/aergoio/aergo/v2/consensus/impl/dpos/bp" + "github.com/aergoio/aergo/v2/contract/system" "github.com/aergoio/aergo/v2/state" "github.com/aergoio/aergo/v2/types" ) diff --git a/consensus/impl/raftv2/blockfactory.go b/consensus/impl/raftv2/blockfactory.go index dc9afb111..2a4f30ac4 100644 --- a/consensus/impl/raftv2/blockfactory.go +++ b/consensus/impl/raftv2/blockfactory.go @@ -513,7 +513,7 @@ func (bf *BlockFactory) generateBlock(work *Work) (*types.Block, *state.BlockSta bestBlock.GetHeader().GetBlocksRootHash(), state.SetPrevBlockHash(bestBlock.BlockHash()), ) - blockState.SetGasPrice(system.GetGasPriceFromState(blockState)) + blockState.SetGasPrice(system.GetGasPrice()) blockState.Receipts().SetHardFork(bf.bv, bi.No) block, err := chain.NewBlockGenerator(bf, bi, blockState, txOp, RaftSkipEmptyBlock).GenerateBlock() diff --git a/consensus/impl/sbp/sbp.go b/consensus/impl/sbp/sbp.go index 48e6b5994..36d7cc2fb 100644 --- a/consensus/impl/sbp/sbp.go +++ b/consensus/impl/sbp/sbp.go @@ -187,7 +187,7 @@ func (s *SimpleBlockFactory) Start() { prevBlock.GetHeader().GetBlocksRootHash(), state.SetPrevBlockHash(prevBlock.BlockHash()), ) - blockState.SetGasPrice(system.GetGasPriceFromState(blockState)) + blockState.SetGasPrice(system.GetGasPrice()) blockState.Receipts().SetHardFork(s.bv, bi.No) txOp := chain.NewCompTxOp(s.txOp, newTxExec(s.ChainDB, bi)) diff --git a/contract/name/execute.go b/contract/name/execute.go index b3858f425..07056cd21 100644 --- a/contract/name/execute.go +++ b/contract/name/execute.go @@ -103,7 +103,7 @@ func ValidateNameTx(tx *types.TxBody, sender *state.V, switch ci.Name { case types.NameCreate: - namePrice := system.GetNamePriceFromState(systemcs) + namePrice := system.GetNamePrice() if namePrice.Cmp(tx.GetAmountBigInt()) > 0 { return nil, types.ErrTooSmallAmount } @@ -112,7 +112,7 @@ func ValidateNameTx(tx *types.TxBody, sender *state.V, return nil, fmt.Errorf("aleady occupied %s", string(name)) } case types.NameUpdate: - namePrice := system.GetNamePriceFromState(systemcs) + namePrice := system.GetNamePrice() if namePrice.Cmp(tx.GetAmountBigInt()) > 0 { return nil, types.ErrTooSmallAmount } diff --git a/contract/system/validation.go b/contract/system/validation.go index cf3fcd37c..33573835c 100644 --- a/contract/system/validation.go +++ b/contract/system/validation.go @@ -130,7 +130,7 @@ func validateForStaking(account []byte, txBody *types.TxBody, scs *state.Contrac return nil, types.ErrLessTimeHasPassed } toBe := new(big.Int).Add(staked.GetAmountBigInt(), txBody.GetAmountBigInt()) - stakingMin := GetStakingMinimumFromState(scs) + stakingMin := GetStakingMinimum() if stakingMin.Cmp(toBe) > 0 { return nil, types.ErrTooSmallAmount } @@ -164,7 +164,7 @@ func validateForUnstaking(account []byte, txBody *types.TxBody, scs *state.Contr return nil, types.ErrLessTimeHasPassed } toBe := new(big.Int).Sub(staked.GetAmountBigInt(), txBody.GetAmountBigInt()) - stakingMin := GetStakingMinimumFromState(scs) + stakingMin := GetStakingMinimum() if toBe.Cmp(big.NewInt(0)) != 0 && stakingMin.Cmp(toBe) > 0 { return nil, types.ErrTooSmallAmount } From 4bf4600850ab20ee4da2f5d5c797e17bac5d310e Mon Sep 17 00:00:00 2001 From: Bernardo Ramos Date: Fri, 15 Sep 2023 01:37:34 -0300 Subject: [PATCH 04/22] fix CommitParams --- contract/system/param.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/contract/system/param.go b/contract/system/param.go index d8f87ae45..71bb309d8 100644 --- a/contract/system/param.go +++ b/contract/system/param.go @@ -88,14 +88,14 @@ func (p parameters) setNextParam(proposalID string, value *big.Int) { } // if a system param was changed, apply or discard its new value -func (p parameters) CommitParams(success bool) { +func CommitParams(success bool) { for i := sysParamIndex(0); i < sysParamMax; i++ { id := i.ID() - if p[id + "next"] != nil { + if systemParams[id + "next"] != nil { if success { - p[id] = p[id + "next"] + systemParams[id] = systemParams[id + "next"] } - p[id + "next"] = nil + systemParams[id + "next"] = nil } } } From 4a716b8e2cb95c25854f916e30f52b911b2a5789 Mon Sep 17 00:00:00 2001 From: Bernardo Ramos Date: Fri, 15 Sep 2023 01:48:39 -0300 Subject: [PATCH 05/22] add some comments [skip ci] --- contract/system/param.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/contract/system/param.go b/contract/system/param.go index 71bb309d8..d06f09866 100644 --- a/contract/system/param.go +++ b/contract/system/param.go @@ -91,10 +91,13 @@ func (p parameters) setNextParam(proposalID string, value *big.Int) { func CommitParams(success bool) { for i := sysParamIndex(0); i < sysParamMax; i++ { id := i.ID() + // check if the param has a new value if systemParams[id + "next"] != nil { if success { + // save the new value for the current block systemParams[id] = systemParams[id + "next"] } + // delete the new value systemParams[id + "next"] = nil } } @@ -102,12 +105,15 @@ func CommitParams(success bool) { // get the param value for the next block func GetNextParam(proposalID string) *big.Int { + // check the value for the next block if val, ok := systemParams[proposalID + "next"]; ok { return val } + // check the value for the current block if val, ok := systemParams[proposalID]; ok { return val } + // default value return DefaultParams[proposalID] } From 1e4b0dfd133a385275fd5fda20ce9c4f463d2115 Mon Sep 17 00:00:00 2001 From: Bernardo Ramos Date: Fri, 15 Sep 2023 06:58:05 +0000 Subject: [PATCH 06/22] fix tests --- contract/system/execute_test.go | 37 ++++++++++++++++++++++++++++---- contract/system/proposal_test.go | 29 +++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 4 deletions(-) diff --git a/contract/system/execute_test.go b/contract/system/execute_test.go index 82ae494b7..e7aa4955d 100644 --- a/contract/system/execute_test.go +++ b/contract/system/execute_test.go @@ -720,6 +720,9 @@ func TestProposalExecute2(t *testing.T) { blockInfo.No++ blockInfo.ForkVersion = config.AllEnabledHardforkConfig.Version(blockInfo.No) + + // BP Count + votingTx := &types.Tx{ Body: &types.TxBody{ Account: sender.ID(), @@ -747,6 +750,9 @@ func TestProposalExecute2(t *testing.T) { internalVoteResult, err := loadVoteResult(scs, GenProposalKey(bpCount.ID())) assert.Equal(t, new(big.Int).Mul(balance2, big.NewInt(3)), internalVoteResult.GetTotal(), "check result total") + + // Staking Min + votingTx = &types.Tx{ Body: &types.TxBody{ Account: sender.ID(), @@ -765,6 +771,11 @@ func TestProposalExecute2(t *testing.T) { _, err = ExecuteSystemTx(scs, votingTx.GetBody(), sender3, receiver, blockInfo) assert.NoError(t, err, "could not execute system tx") + + // Gas Price + + origGasPrice := GetGasPrice() + votingTx = &types.Tx{ Body: &types.TxBody{ Account: sender.ID(), @@ -782,8 +793,16 @@ func TestProposalExecute2(t *testing.T) { votingTx.Body.Payload = []byte(`{"Name":"v1voteDAO", "Args":["GASPRICE", "1004"]}`) _, err = ExecuteSystemTx(scs, votingTx.GetBody(), sender3, receiver, blockInfo) assert.NoError(t, err, "could not execute system tx") - gasPrice := GetGasPrice() - assert.Equal(t, balance0_5, gasPrice, "result of gas price voting") + + // check the value for the current block + assert.Equal(t, origGasPrice, GetGasPrice(), "result of gas price voting") + // check the value for the next block + assert.Equal(t, balance0_5, GetNextParam("GASPRICE"), "result of gas price voting") + // commit the new value + CommitParams(true) + // check the value for the current block + assert.Equal(t, balance0_5, GetGasPrice(), "result of gas price voting") + blockInfo.No += StakingDelay unstakingTx := &types.Tx{ @@ -815,6 +834,9 @@ func TestProposalExecute2(t *testing.T) { _, err = ExecuteSystemTx(scs, unstakingTx.GetBody(), sender, receiver, blockInfo) assert.NoError(t, err, "could not execute system tx") + + oldNamePrice := GetNamePrice() + votingTx.Body.Account = sender2.ID() votingTx.Body.Payload = []byte(`{"Name":"v1voteDAO", "Args":["NAMEPRICE", "1004"]}`) _, err = ExecuteSystemTx(scs, votingTx.GetBody(), sender2, receiver, blockInfo) @@ -830,8 +852,15 @@ func TestProposalExecute2(t *testing.T) { internalVoteResult, err = loadVoteResult(scs, GenProposalKey(namePrice.ID())) assert.Equal(t, new(big.Int).Mul(balance2, big.NewInt(2)), internalVoteResult.GetTotal(), "check result total") assert.Equal(t, "1004", string(voteResult.Votes[0].Candidate), "1st place") - currentNamePrice := GetNamePrice() - assert.Equal(t, "1004", currentNamePrice.String(), "current name price") + + // check the value for the current block + assert.Equal(t, oldNamePrice, GetNamePrice(), "check name price") + // check the value for the next block + assert.Equal(t, big.NewInt(1004), GetNextParam("NAMEPRICE"), "check name price") + // commit the new value + CommitParams(true) + // check the value for the current block + assert.Equal(t, big.NewInt(1004), GetNamePrice(), "check name price") /* blockInfo += StakingDelay diff --git a/contract/system/proposal_test.go b/contract/system/proposal_test.go index e462508d9..4ffa83560 100644 --- a/contract/system/proposal_test.go +++ b/contract/system/proposal_test.go @@ -123,6 +123,14 @@ func TestProposalBPCount(t *testing.T) { _, err = ExecuteSystemTx(scs, validCandiTx.GetBody(), sender2, receiver, blockInfo) assert.NoError(t, err, "valid") + + // check the value for the current block + assert.Equal(t, 3, GetBpCount(), "check bp") + // check the value for the next block + assert.Equal(t, big.NewInt(13), GetNextParam("BPCOUNT"), "check bp") + // commit the new value + CommitParams(true) + // check the value for the current block assert.Equal(t, 13, GetBpCount(), "check bp") } @@ -203,8 +211,21 @@ func TestFailProposals(t *testing.T) { _, err = ExecuteSystemTx(scs, validCandiTx.GetBody(), sender2, receiver, blockInfo) assert.NoError(t, err, "valid") + + // check the value for the current block + assert.Equal(t, 3, GetBpCount(), "check bp") + // check the value for the next block + assert.Equal(t, big.NewInt(13), GetNextParam("BPCOUNT"), "check bp") + // commit the new value + CommitParams(true) + // check the value for the current block assert.Equal(t, 13, GetBpCount(), "check bp") + + // gas price + + oldGasPrice := GetGasPrice() + invalidCandiTx.Body.Payload = []byte(`{"Name":"v1voteDAO", "Args":["gasprice", "500000000000000000000000001"]}`) _, err = ExecuteSystemTx(scs, invalidCandiTx.GetBody(), sender, receiver, blockInfo) assert.Error(t, err, "invalid range") @@ -221,5 +242,13 @@ func TestFailProposals(t *testing.T) { validCandiTx.Body.Payload = []byte(`{"Name":"v1voteDAO", "Args":["gasprice", "101"]}`) _, err = ExecuteSystemTx(scs, validCandiTx.GetBody(), sender2, receiver, blockInfo) assert.NoError(t, err, "valid") + + // check the value for the current block + assert.Equal(t, oldGasPrice, GetGasPrice(), "check gas price") + // check the value for the next block + assert.Equal(t, big.NewInt(101), GetNextParam("GASPRICE"), "check gas price") + // commit the new value + CommitParams(true) + // check the value for the current block assert.Equal(t, big.NewInt(101), GetGasPrice(), "check gas price") } From bf889a08d15cab9480825428518b0d09914cae93 Mon Sep 17 00:00:00 2001 From: Bernardo Ramos Date: Mon, 25 Sep 2023 04:31:40 +0000 Subject: [PATCH 07/22] discard new params on chain reorg --- consensus/impl/dpos/status.go | 2 ++ contract/system/param.go | 10 +++++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/consensus/impl/dpos/status.go b/consensus/impl/dpos/status.go index 85ccd9ed9..b6e8f739c 100644 --- a/consensus/impl/dpos/status.go +++ b/consensus/impl/dpos/status.go @@ -116,6 +116,8 @@ func (s *Status) Update(block *types.Block) { } // if a system param was changed, discard its new value + // this is mainly for block revert case + // the params are reloaded from db on block reorganization system.CommitParams(false) } diff --git a/contract/system/param.go b/contract/system/param.go index d06f09866..f665acd0d 100644 --- a/contract/system/param.go +++ b/contract/system/param.go @@ -40,7 +40,11 @@ func genParamKey(id string) []byte { return []byte("param\\" + strings.ToUpper(id)) } +// This is also called on chain reorganization func InitSystemParams(g dataGetter, bpCount int) { + // discard any new params computed for the next block + CommitParams(false) + // (re)load param values from database initDefaultBpCount(bpCount) systemParams = loadParams(g) } @@ -88,13 +92,13 @@ func (p parameters) setNextParam(proposalID string, value *big.Int) { } // if a system param was changed, apply or discard its new value -func CommitParams(success bool) { +func CommitParams(apply bool) { for i := sysParamIndex(0); i < sysParamMax; i++ { id := i.ID() // check if the param has a new value if systemParams[id + "next"] != nil { - if success { - // save the new value for the current block + if apply { + // set the new value for the current block systemParams[id] = systemParams[id + "next"] } // delete the new value From 05181f97ca208f41fd07b1227f62e634c3c0edaa Mon Sep 17 00:00:00 2001 From: Bernardo Ramos Date: Tue, 3 Oct 2023 05:58:58 +0000 Subject: [PATCH 08/22] test random numbers on the same transaction --- contract/vm_dummy/test_files/type_random.lua | 15 ++++++-- .../test_files/type_random_caller.lua | 35 +++++++++++++++++++ contract/vm_dummy/vm_dummy_test.go | 19 ++++++++-- 3 files changed, 64 insertions(+), 5 deletions(-) create mode 100644 contract/vm_dummy/test_files/type_random_caller.lua diff --git a/contract/vm_dummy/test_files/type_random.lua b/contract/vm_dummy/test_files/type_random.lua index e7fe68929..47f63d23c 100644 --- a/contract/vm_dummy/test_files/type_random.lua +++ b/contract/vm_dummy/test_files/type_random.lua @@ -1,5 +1,16 @@ function random(...) - return system.random(...) + return system.random(...) end -abi.register(random) +function get_numbers(count) + local list = {} + + for i = 1, count do + local num = system.random(1, 100) + table.insert(list, num) + end + + return list +end + +abi.register(random, get_numbers) diff --git a/contract/vm_dummy/test_files/type_random_caller.lua b/contract/vm_dummy/test_files/type_random_caller.lua new file mode 100644 index 000000000..9e87c9c6d --- /dev/null +++ b/contract/vm_dummy/test_files/type_random_caller.lua @@ -0,0 +1,35 @@ +-- check if numbers generated by a called contract are +-- the same if called on the same transaction +function check_if_equal(address) + + local list1 = contract.call(address, 'get_numbers', 10) + local list2 = contract.call(address, 'get_numbers', 10) + local list3 = contract.call(address, 'get_numbers', 10) + + if lists_are_equal(list1, list2) then + return true + end + if lists_are_equal(list2, list3) then + return true + end + + return false +end + +function lists_are_equal(list1, list2) + -- check if lengths are different + if #list1 ~= #list2 then + return false + end + + -- compare each element + for i = 1, #list1 do + if list1[i] ~= list2[i] then + return false + end + end + + return true +end + +abi.register(check_if_equal) diff --git a/contract/vm_dummy/vm_dummy_test.go b/contract/vm_dummy/vm_dummy_test.go index ddfb6f43b..6641f5083 100644 --- a/contract/vm_dummy/vm_dummy_test.go +++ b/contract/vm_dummy/vm_dummy_test.go @@ -2074,14 +2074,20 @@ func checkRandomIntValue(v string, min, max int) error { } func TestTypeRandom(t *testing.T) { - code := readLuaCode("type_random.lua") - require.NotEmpty(t, code, "failed to read type_random.lua") + code1 := readLuaCode("type_random.lua") + require.NotEmpty(t, code1, "failed to read type_random.lua") + code2 := readLuaCode("type_random_caller.lua") + require.NotEmpty(t, code2, "failed to read type_random_caller.lua") bc, err := LoadDummyChain() require.NoErrorf(t, err, "failed to create dummy chain") defer bc.Release() - err = bc.ConnectBlock(NewLuaTxAccount("user1", 1, types.Aergo), NewLuaTxDeploy("user1", "random", 0, code)) + err = bc.ConnectBlock( + NewLuaTxAccount("user1", 1, types.Aergo), + NewLuaTxDeploy("user1", "random", 0, code1), + NewLuaTxDeploy("user1", "caller", 0, code2), + ) require.NoErrorf(t, err, "failed to deploy") err = bc.ConnectBlock(NewLuaTxCall("user1", "random", 0, `{"Name": "random", "Args":[]}`).Fail("1 or 2 arguments required")) @@ -2117,6 +2123,13 @@ func TestTypeRandom(t *testing.T) { err = bc.Query("random", `{"Name": "random", "Args":[3,1]}`, "system.random: the maximum value must be greater than the minimum value", "") require.NoErrorf(t, err, "failed to query") + + tx = NewLuaTxCall("user1", "caller", 0, `{"Name": "check_if_equal", "Args":["`+nameToAddress("random")+`"]}`) + err = bc.ConnectBlock(tx) + require.NoErrorf(t, err, "failed to call tx") + receipt = bc.GetReceipt(tx.Hash()) + assert.Equalf(t, `false`, receipt.GetRet(), "random numbers are the same on the same transaction") + } func TestTypeSparseTable(t *testing.T) { From 3798daad565c4440a8847215b04a2f462a6d41e7 Mon Sep 17 00:00:00 2001 From: kch Date: Thu, 5 Oct 2023 02:51:32 +0000 Subject: [PATCH 09/22] add mutex in params to prevent panic --- contract/system/execute_test.go | 5 -- contract/system/param.go | 97 +++++++++++++++++++++++--------- contract/system/param_test.go | 12 ++-- contract/system/proposal_test.go | 3 +- 4 files changed, 76 insertions(+), 41 deletions(-) diff --git a/contract/system/execute_test.go b/contract/system/execute_test.go index fe02c694b..abe293f56 100644 --- a/contract/system/execute_test.go +++ b/contract/system/execute_test.go @@ -720,7 +720,6 @@ func TestProposalExecute2(t *testing.T) { blockInfo.No++ blockInfo.ForkVersion = config.AllEnabledHardforkConfig.Version(blockInfo.No) - // BP Count votingTx := &types.Tx{ @@ -750,7 +749,6 @@ func TestProposalExecute2(t *testing.T) { internalVoteResult, err := loadVoteResult(scs, GenProposalKey(bpCount.ID())) assert.Equal(t, new(big.Int).Mul(balance2, big.NewInt(3)), internalVoteResult.GetTotal(), "check result total") - // Staking Min votingTx = &types.Tx{ @@ -771,7 +769,6 @@ func TestProposalExecute2(t *testing.T) { _, err = ExecuteSystemTx(scs, votingTx.GetBody(), sender3, receiver, blockInfo) assert.NoError(t, err, "could not execute system tx") - // Gas Price origGasPrice := GetGasPrice() @@ -803,7 +800,6 @@ func TestProposalExecute2(t *testing.T) { // check the value for the current block assert.Equal(t, balance0_5, GetGasPrice(), "result of gas price voting") - blockInfo.No += StakingDelay unstakingTx := &types.Tx{ Body: &types.TxBody{ @@ -834,7 +830,6 @@ func TestProposalExecute2(t *testing.T) { _, err = ExecuteSystemTx(scs, unstakingTx.GetBody(), sender, receiver, blockInfo) assert.NoError(t, err, "could not execute system tx") - oldNamePrice := GetNamePrice() votingTx.Body.Account = sender2.ID() diff --git a/contract/system/param.go b/contract/system/param.go index f665acd0d..5496387f6 100644 --- a/contract/system/param.go +++ b/contract/system/param.go @@ -3,12 +3,51 @@ package system import ( "math/big" "strings" + "sync" "github.com/aergoio/aergo/v2/state" "github.com/aergoio/aergo/v2/types" ) -type parameters map[string]*big.Int +type parameters struct { + mtx sync.Mutex + params map[string]*big.Int +} + +func (p *parameters) setParam(proposalID string, value *big.Int) { + p.mtx.Lock() + defer p.mtx.Unlock() + + p.params[proposalID] = value +} + +// save the new value for the param, to be active on the next block +func (p *parameters) setNextParam(proposalID string, value *big.Int) { + p.mtx.Lock() + defer p.mtx.Unlock() + + p.params[nextParamKey(proposalID)] = value +} + +// save the new value for the param, to be active on the next block +func (p *parameters) delNextParam(proposalID string) { + p.mtx.Lock() + defer p.mtx.Unlock() + + delete(p.params, nextParamKey(proposalID)) +} + +func (p *parameters) getNextParam(proposalID string) *big.Int { + return p.params[nextParamKey(proposalID)] +} + +func (p *parameters) getParam(proposalID string) *big.Int { + return p.params[proposalID] +} + +func nextParamKey(id string) string { + return id + "next" +} const ( RESET = -1 @@ -26,13 +65,19 @@ const ( ) var ( - systemParams parameters + systemParams *parameters = ¶meters{ + mtx: sync.Mutex{}, + params: map[string]*big.Int{}, + } //DefaultParams is for aergo v1 compatibility - DefaultParams = map[string]*big.Int{ - stakingMin.ID(): types.StakingMinimum, - gasPrice.ID(): types.NewAmount(50, types.Gaer), // 50 gaer - namePrice.ID(): types.NewAmount(1, types.Aergo), // 1 aergo + DefaultParams *parameters = ¶meters{ + mtx: sync.Mutex{}, + params: map[string]*big.Int{ + stakingMin.ID(): types.StakingMinimum, + gasPrice.ID(): types.NewAmount(50, types.Gaer), // 50 gaer + namePrice.ID(): types.NewAmount(1, types.Aergo), // 1 aergo + }, } ) @@ -53,13 +98,13 @@ func InitSystemParams(g dataGetter, bpCount int) { // services start. func initDefaultBpCount(count int) { // Ensure that it is not modified after it is initialized. - if DefaultParams[bpCount.ID()] == nil { - DefaultParams[bpCount.ID()] = big.NewInt(int64(count)) + if DefaultParams.getParam(bpCount.ID()) == nil { + DefaultParams.setParam(bpCount.ID(), big.NewInt(int64(count))) } } // load the params from the database or use the default values -func loadParams(g dataGetter) parameters { +func loadParams(g dataGetter) *parameters { ret := map[string]*big.Int{} for i := sysParamIndex(0); i < sysParamMax; i++ { id := i.ID() @@ -70,13 +115,16 @@ func loadParams(g dataGetter) parameters { if data != nil { ret[id] = new(big.Int).SetBytes(data) } else { - ret[id] = DefaultParams[id] + ret[id] = DefaultParams.getParam(id) } } - return ret + return ¶meters{ + mtx: sync.Mutex{}, + params: ret, + } } -func updateParam(s dataSetter, id string, value *big.Int) (error) { +func updateParam(s dataSetter, id string, value *big.Int) error { // save the param to the database (in a db txn, commit when the block is connected) if err := s.SetData(genParamKey(id), value.Bytes()); err != nil { return err @@ -86,23 +134,18 @@ func updateParam(s dataSetter, id string, value *big.Int) (error) { return nil } -// save the new value for the param, to be active on the next block -func (p parameters) setNextParam(proposalID string, value *big.Int) { - p[proposalID + "next"] = value -} - // if a system param was changed, apply or discard its new value func CommitParams(apply bool) { for i := sysParamIndex(0); i < sysParamMax; i++ { id := i.ID() // check if the param has a new value - if systemParams[id + "next"] != nil { + if param := systemParams.getNextParam(id); param != nil { if apply { // set the new value for the current block - systemParams[id] = systemParams[id + "next"] + systemParams.setParam(id, param) } // delete the new value - systemParams[id + "next"] = nil + systemParams.delNextParam(id) } } } @@ -110,27 +153,26 @@ func CommitParams(apply bool) { // get the param value for the next block func GetNextParam(proposalID string) *big.Int { // check the value for the next block - if val, ok := systemParams[proposalID + "next"]; ok { + if val := systemParams.getNextParam(proposalID); val != nil { return val } // check the value for the current block - if val, ok := systemParams[proposalID]; ok { + if val := systemParams.getParam(proposalID); val != nil { return val } // default value - return DefaultParams[proposalID] + return DefaultParams.getParam(proposalID) } // get the param value for the current block func GetParam(proposalID string) *big.Int { - if val, ok := systemParams[proposalID]; ok { + if val := systemParams.getParam(proposalID); val != nil { return val } - return DefaultParams[proposalID] + return DefaultParams.getParam(proposalID) } // these 4 functions are reading the param value for the current block - func GetStakingMinimum() *big.Int { return GetParam(stakingMin.ID()) } @@ -148,7 +190,6 @@ func GetBpCount() int { } // these functions are reading the param value directly from the state - func GetNamePriceFromState(scs *state.ContractState) *big.Int { return getParamFromState(scs, namePrice) } @@ -171,7 +212,7 @@ func getParamFromState(scs *state.ContractState, id sysParamIndex) *big.Int { panic("could not get blockchain parameter") } if data == nil { - return DefaultParams[id.ID()] + return DefaultParams.getParam(id.ID()) } return new(big.Int).SetBytes(data) } diff --git a/contract/system/param_test.go b/contract/system/param_test.go index e9812c92e..38312c69a 100644 --- a/contract/system/param_test.go +++ b/contract/system/param_test.go @@ -8,17 +8,17 @@ import ( func TestValidateDefaultParams(t *testing.T) { // Staking minimum amount ( 10,000 aergo ) - stakingMin, ok := DefaultParams[stakingMin.ID()] - assert.Truef(t, ok, "stakingMin is not valid. check contract/system/param.go") + stakingMin := DefaultParams.getParam(stakingMin.ID()) + assert.NotNilf(t, stakingMin, "stakingMin is not valid. check contract/system/param.go") assert.Equalf(t, "10000000000000000000000", stakingMin.String(), "StakingMinimum is not valid. check contract/system/param.go") // gas price ( 50 gaer ) - gasPrice, ok := DefaultParams[gasPrice.ID()] - assert.Truef(t, ok, "gasPrice is not valid. check contract/system/param.go") + gasPrice := DefaultParams.getParam(gasPrice.ID()) + assert.NotNilf(t, gasPrice, "gasPrice is not valid. check contract/system/param.go") assert.Equalf(t, "50000000000", gasPrice.String(), "GasPrice is not valid. check contract/system/param.go") // Proposal price ( 1 aergo ) - namePrice := DefaultParams[namePrice.ID()] - assert.Truef(t, ok, "namePrice is not valid. check contract/system/param.go") + namePrice := DefaultParams.getParam(namePrice.ID()) + assert.NotNilf(t, namePrice, "namePrice is not valid. check contract/system/param.go") assert.Equalf(t, "1000000000000000000", namePrice.String(), "ProposalPrice is not valid. check contract/system/param.go") } diff --git a/contract/system/proposal_test.go b/contract/system/proposal_test.go index 4ffa83560..b2376d674 100644 --- a/contract/system/proposal_test.go +++ b/contract/system/proposal_test.go @@ -221,7 +221,6 @@ func TestFailProposals(t *testing.T) { // check the value for the current block assert.Equal(t, 13, GetBpCount(), "check bp") - // gas price oldGasPrice := GetGasPrice() @@ -237,7 +236,7 @@ func TestFailProposals(t *testing.T) { validCandiTx.Body.Payload = []byte(`{"Name":"v1voteDAO", "Args":["gasprice", "101"]}`) _, err = ExecuteSystemTx(scs, validCandiTx.GetBody(), sender, receiver, blockInfo) assert.NoError(t, err, "valid") - assert.Equal(t, DefaultParams[gasPrice.ID()], GetGasPrice(), "check gas price") + assert.Equal(t, DefaultParams.getParam(gasPrice.ID()), GetGasPrice(), "check gas price") validCandiTx.Body.Payload = []byte(`{"Name":"v1voteDAO", "Args":["gasprice", "101"]}`) _, err = ExecuteSystemTx(scs, validCandiTx.GetBody(), sender2, receiver, blockInfo) From b1d0561cb51414a495a09e2873d9cae80b458bb4 Mon Sep 17 00:00:00 2001 From: kch Date: Thu, 5 Oct 2023 03:08:59 +0000 Subject: [PATCH 10/22] update mutex to rwmutex --- contract/system/param.go | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/contract/system/param.go b/contract/system/param.go index 5496387f6..4d5095c71 100644 --- a/contract/system/param.go +++ b/contract/system/param.go @@ -10,7 +10,7 @@ import ( ) type parameters struct { - mtx sync.Mutex + mtx sync.RWMutex params map[string]*big.Int } @@ -38,10 +38,16 @@ func (p *parameters) delNextParam(proposalID string) { } func (p *parameters) getNextParam(proposalID string) *big.Int { + p.mtx.Lock() + defer p.mtx.Unlock() + return p.params[nextParamKey(proposalID)] } func (p *parameters) getParam(proposalID string) *big.Int { + p.mtx.Lock() + defer p.mtx.Unlock() + return p.params[proposalID] } @@ -66,13 +72,13 @@ const ( var ( systemParams *parameters = ¶meters{ - mtx: sync.Mutex{}, + mtx: sync.RWMutex{}, params: map[string]*big.Int{}, } //DefaultParams is for aergo v1 compatibility DefaultParams *parameters = ¶meters{ - mtx: sync.Mutex{}, + mtx: sync.RWMutex{}, params: map[string]*big.Int{ stakingMin.ID(): types.StakingMinimum, gasPrice.ID(): types.NewAmount(50, types.Gaer), // 50 gaer @@ -119,7 +125,7 @@ func loadParams(g dataGetter) *parameters { } } return ¶meters{ - mtx: sync.Mutex{}, + mtx: sync.RWMutex{}, params: ret, } } From 083335da9219445d76a0adccad80a55c57c82e3d Mon Sep 17 00:00:00 2001 From: kch Date: Thu, 5 Oct 2023 03:58:31 +0000 Subject: [PATCH 11/22] rollback defaultParams --- contract/system/param.go | 25 ++++++++++--------------- contract/system/param_test.go | 6 +++--- contract/system/proposal_test.go | 2 +- 3 files changed, 14 insertions(+), 19 deletions(-) diff --git a/contract/system/param.go b/contract/system/param.go index 4d5095c71..59a802c7e 100644 --- a/contract/system/param.go +++ b/contract/system/param.go @@ -29,7 +29,6 @@ func (p *parameters) setNextParam(proposalID string, value *big.Int) { p.params[nextParamKey(proposalID)] = value } -// save the new value for the param, to be active on the next block func (p *parameters) delNextParam(proposalID string) { p.mtx.Lock() defer p.mtx.Unlock() @@ -40,7 +39,6 @@ func (p *parameters) delNextParam(proposalID string) { func (p *parameters) getNextParam(proposalID string) *big.Int { p.mtx.Lock() defer p.mtx.Unlock() - return p.params[nextParamKey(proposalID)] } @@ -77,13 +75,10 @@ var ( } //DefaultParams is for aergo v1 compatibility - DefaultParams *parameters = ¶meters{ - mtx: sync.RWMutex{}, - params: map[string]*big.Int{ - stakingMin.ID(): types.StakingMinimum, - gasPrice.ID(): types.NewAmount(50, types.Gaer), // 50 gaer - namePrice.ID(): types.NewAmount(1, types.Aergo), // 1 aergo - }, + DefaultParams map[string]*big.Int = map[string]*big.Int{ + stakingMin.ID(): types.StakingMinimum, + gasPrice.ID(): types.NewAmount(50, types.Gaer), // 50 gaer + namePrice.ID(): types.NewAmount(1, types.Aergo), // 1 aergo } ) @@ -104,8 +99,8 @@ func InitSystemParams(g dataGetter, bpCount int) { // services start. func initDefaultBpCount(count int) { // Ensure that it is not modified after it is initialized. - if DefaultParams.getParam(bpCount.ID()) == nil { - DefaultParams.setParam(bpCount.ID(), big.NewInt(int64(count))) + if DefaultParams[bpCount.ID()] == nil { + DefaultParams[bpCount.ID()] = big.NewInt(int64(count)) } } @@ -121,7 +116,7 @@ func loadParams(g dataGetter) *parameters { if data != nil { ret[id] = new(big.Int).SetBytes(data) } else { - ret[id] = DefaultParams.getParam(id) + ret[id] = DefaultParams[id] } } return ¶meters{ @@ -167,7 +162,7 @@ func GetNextParam(proposalID string) *big.Int { return val } // default value - return DefaultParams.getParam(proposalID) + return DefaultParams[proposalID] } // get the param value for the current block @@ -175,7 +170,7 @@ func GetParam(proposalID string) *big.Int { if val := systemParams.getParam(proposalID); val != nil { return val } - return DefaultParams.getParam(proposalID) + return DefaultParams[proposalID] } // these 4 functions are reading the param value for the current block @@ -218,7 +213,7 @@ func getParamFromState(scs *state.ContractState, id sysParamIndex) *big.Int { panic("could not get blockchain parameter") } if data == nil { - return DefaultParams.getParam(id.ID()) + return DefaultParams[id.ID()] } return new(big.Int).SetBytes(data) } diff --git a/contract/system/param_test.go b/contract/system/param_test.go index 38312c69a..f23c601ab 100644 --- a/contract/system/param_test.go +++ b/contract/system/param_test.go @@ -8,17 +8,17 @@ import ( func TestValidateDefaultParams(t *testing.T) { // Staking minimum amount ( 10,000 aergo ) - stakingMin := DefaultParams.getParam(stakingMin.ID()) + stakingMin := DefaultParams[stakingMin.ID()] assert.NotNilf(t, stakingMin, "stakingMin is not valid. check contract/system/param.go") assert.Equalf(t, "10000000000000000000000", stakingMin.String(), "StakingMinimum is not valid. check contract/system/param.go") // gas price ( 50 gaer ) - gasPrice := DefaultParams.getParam(gasPrice.ID()) + gasPrice := DefaultParams[gasPrice.ID()] assert.NotNilf(t, gasPrice, "gasPrice is not valid. check contract/system/param.go") assert.Equalf(t, "50000000000", gasPrice.String(), "GasPrice is not valid. check contract/system/param.go") // Proposal price ( 1 aergo ) - namePrice := DefaultParams.getParam(namePrice.ID()) + namePrice := DefaultParams[namePrice.ID()] assert.NotNilf(t, namePrice, "namePrice is not valid. check contract/system/param.go") assert.Equalf(t, "1000000000000000000", namePrice.String(), "ProposalPrice is not valid. check contract/system/param.go") } diff --git a/contract/system/proposal_test.go b/contract/system/proposal_test.go index b2376d674..c35ad1516 100644 --- a/contract/system/proposal_test.go +++ b/contract/system/proposal_test.go @@ -236,7 +236,7 @@ func TestFailProposals(t *testing.T) { validCandiTx.Body.Payload = []byte(`{"Name":"v1voteDAO", "Args":["gasprice", "101"]}`) _, err = ExecuteSystemTx(scs, validCandiTx.GetBody(), sender, receiver, blockInfo) assert.NoError(t, err, "valid") - assert.Equal(t, DefaultParams.getParam(gasPrice.ID()), GetGasPrice(), "check gas price") + assert.Equal(t, DefaultParams[gasPrice.ID()], GetGasPrice(), "check gas price") validCandiTx.Body.Payload = []byte(`{"Name":"v1voteDAO", "Args":["gasprice", "101"]}`) _, err = ExecuteSystemTx(scs, validCandiTx.GetBody(), sender2, receiver, blockInfo) From 0bad16c99ac68b837d90d11fd41924f32a8be52c Mon Sep 17 00:00:00 2001 From: Bernardo Ramos Date: Thu, 5 Oct 2023 04:09:58 +0000 Subject: [PATCH 12/22] rename mutex variable --- contract/system/param.go | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/contract/system/param.go b/contract/system/param.go index 59a802c7e..07d8ad90b 100644 --- a/contract/system/param.go +++ b/contract/system/param.go @@ -10,41 +10,42 @@ import ( ) type parameters struct { - mtx sync.RWMutex + mutex sync.RWMutex params map[string]*big.Int } func (p *parameters) setParam(proposalID string, value *big.Int) { - p.mtx.Lock() - defer p.mtx.Unlock() + p.mutex.Lock() + defer p.mutex.Unlock() p.params[proposalID] = value } // save the new value for the param, to be active on the next block func (p *parameters) setNextParam(proposalID string, value *big.Int) { - p.mtx.Lock() - defer p.mtx.Unlock() + p.mutex.Lock() + defer p.mutex.Unlock() p.params[nextParamKey(proposalID)] = value } func (p *parameters) delNextParam(proposalID string) { - p.mtx.Lock() - defer p.mtx.Unlock() + p.mutex.Lock() + defer p.mutex.Unlock() delete(p.params, nextParamKey(proposalID)) } func (p *parameters) getNextParam(proposalID string) *big.Int { - p.mtx.Lock() - defer p.mtx.Unlock() + p.mutex.Lock() + defer p.mutex.Unlock() + return p.params[nextParamKey(proposalID)] } func (p *parameters) getParam(proposalID string) *big.Int { - p.mtx.Lock() - defer p.mtx.Unlock() + p.mutex.Lock() + defer p.mutex.Unlock() return p.params[proposalID] } @@ -70,12 +71,12 @@ const ( var ( systemParams *parameters = ¶meters{ - mtx: sync.RWMutex{}, + mutex: sync.RWMutex{}, params: map[string]*big.Int{}, } //DefaultParams is for aergo v1 compatibility - DefaultParams map[string]*big.Int = map[string]*big.Int{ + DefaultParams = map[string]*big.Int{ stakingMin.ID(): types.StakingMinimum, gasPrice.ID(): types.NewAmount(50, types.Gaer), // 50 gaer namePrice.ID(): types.NewAmount(1, types.Aergo), // 1 aergo @@ -120,7 +121,7 @@ func loadParams(g dataGetter) *parameters { } } return ¶meters{ - mtx: sync.RWMutex{}, + mutex: sync.RWMutex{}, params: ret, } } @@ -174,6 +175,7 @@ func GetParam(proposalID string) *big.Int { } // these 4 functions are reading the param value for the current block + func GetStakingMinimum() *big.Int { return GetParam(stakingMin.ID()) } @@ -191,6 +193,7 @@ func GetBpCount() int { } // these functions are reading the param value directly from the state + func GetNamePriceFromState(scs *state.ContractState) *big.Int { return getParamFromState(scs, namePrice) } From fbe27e53cf91db1fcca97da3ce948b18507f4ee6 Mon Sep 17 00:00:00 2001 From: kch Date: Thu, 5 Oct 2023 05:27:38 +0000 Subject: [PATCH 13/22] remove unused args ( systemContractState ) tidy codes --- contract/name/execute.go | 58 ++++++++++++++++---------------------- contract/name/name.go | 2 +- contract/name/name_test.go | 3 +- 3 files changed, 26 insertions(+), 37 deletions(-) diff --git a/contract/name/execute.go b/contract/name/execute.go index bae86d031..9f88b9b63 100644 --- a/contract/name/execute.go +++ b/contract/name/execute.go @@ -14,15 +14,11 @@ import ( func ExecuteNameTx(bs *state.BlockState, scs *state.ContractState, txBody *types.TxBody, sender, receiver *state.V, blockInfo *types.BlockHeaderInfo) ([]*types.Event, error) { - systemContractState, err := bs.StateDB.GetSystemAccountState() - - ci, err := ValidateNameTx(txBody, sender, scs, systemContractState) + ci, err := ValidateNameTx(txBody, sender, scs) if err != nil { return nil, err } - var events []*types.Event - var nameState *state.V owner := getOwner(scs, []byte(types.AergoName), false) if owner != nil { @@ -38,17 +34,18 @@ func ExecuteNameTx(bs *state.BlockState, scs *state.ContractState, txBody *types nameState = receiver } + var events []*types.Event switch ci.Name { case types.NameCreate: - if err = CreateName(scs, txBody, sender, nameState, - ci.Args[0].(string)); err != nil { + nameArg := ci.Args[0].(string) + if err = CreateName(scs, txBody, sender, nameState, nameArg); err != nil { return nil, err } jsonArgs := "" if blockInfo.ForkVersion < 2 { - jsonArgs = `{"name":"` + ci.Args[0].(string) + `"}` + jsonArgs = `{"name":"` + nameArg + `"}` } else { - jsonArgs = `["` + ci.Args[0].(string) + `"]` + jsonArgs = `["` + nameArg + `"]` } events = append(events, &types.Event{ ContractAddress: receiver.ID(), @@ -57,16 +54,16 @@ func ExecuteNameTx(bs *state.BlockState, scs *state.ContractState, txBody *types JsonArgs: jsonArgs, }) case types.NameUpdate: - if err = UpdateName(bs, scs, txBody, sender, nameState, - ci.Args[0].(string), ci.Args[1].(string)); err != nil { + nameArg := ci.Args[0].(string) + toArg := ci.Args[1].(string) + if err = UpdateName(bs, scs, txBody, sender, nameState, nameArg, toArg); err != nil { return nil, err } jsonArgs := "" if blockInfo.ForkVersion < 2 { - jsonArgs = `{"name":"` + ci.Args[0].(string) + - `","to":"` + ci.Args[1].(string) + `"}` + jsonArgs = `{"name":"` + nameArg + `","to":"` + toArg + `"}` } else { - jsonArgs = `["` + ci.Args[0].(string) + `","` + ci.Args[1].(string) + `"]` + jsonArgs = `["` + nameArg + `","` + toArg + `"]` } events = append(events, &types.Event{ ContractAddress: receiver.ID(), @@ -75,7 +72,8 @@ func ExecuteNameTx(bs *state.BlockState, scs *state.ContractState, txBody *types JsonArgs: jsonArgs, }) case types.SetContractOwner: - ownerState, err := SetContractOwner(bs, scs, ci.Args[0].(string), nameState) + ownerArg := ci.Args[0].(string) + ownerState, err := SetContractOwner(bs, scs, ownerArg, nameState) if err != nil { return nil, err } @@ -87,9 +85,7 @@ func ExecuteNameTx(bs *state.BlockState, scs *state.ContractState, txBody *types return events, nil } -func ValidateNameTx(tx *types.TxBody, sender *state.V, - scs, systemcs *state.ContractState) (*types.CallInfo, error) { - +func ValidateNameTx(tx *types.TxBody, sender *state.V, scs *state.ContractState) (*types.CallInfo, error) { if sender != nil && sender.Balance().Cmp(tx.GetAmountBigInt()) < 0 { return nil, types.ErrInsufficientBalance } @@ -99,30 +95,25 @@ func ValidateNameTx(tx *types.TxBody, sender *state.V, return nil, err } - name := ci.Args[0].(string) - + nameArg := ci.Args[0].(string) switch ci.Name { case types.NameCreate: - namePrice := system.GetNamePrice() - if namePrice.Cmp(tx.GetAmountBigInt()) > 0 { + if system.GetNamePrice().Cmp(tx.GetAmountBigInt()) > 0 { return nil, types.ErrTooSmallAmount } - owner := getOwner(scs, []byte(name), false) - if owner != nil { - return nil, fmt.Errorf("aleady occupied %s", string(name)) + if owner := getOwner(scs, []byte(nameArg), false); owner != nil { + return nil, fmt.Errorf("aleady occupied %s", string(nameArg)) } case types.NameUpdate: - namePrice := system.GetNamePrice() - if namePrice.Cmp(tx.GetAmountBigInt()) > 0 { + if system.GetNamePrice().Cmp(tx.GetAmountBigInt()) > 0 { return nil, types.ErrTooSmallAmount } - if (!bytes.Equal(tx.Account, []byte(name))) && - (!bytes.Equal(tx.Account, getOwner(scs, []byte(name), false))) { - return nil, fmt.Errorf("owner not matched : %s", name) + if (!bytes.Equal(tx.Account, []byte(nameArg))) && + (!bytes.Equal(tx.Account, getOwner(scs, []byte(nameArg), false))) { + return nil, fmt.Errorf("owner not matched : %s", nameArg) } case types.SetContractOwner: - owner := getOwner(scs, []byte(types.AergoName), false) - if owner != nil { + if owner := getOwner(scs, []byte(types.AergoName), false); owner != nil { return nil, fmt.Errorf("owner aleady set to %s", types.EncodeAddress(owner)) } default: @@ -135,8 +126,6 @@ func ValidateNameTx(tx *types.TxBody, sender *state.V, func SetContractOwner(bs *state.BlockState, scs *state.ContractState, address string, nameState *state.V) (*state.V, error) { - name := []byte(types.AergoName) - rawaddr, err := types.DecodeAddress(address) if err != nil { return nil, err @@ -150,6 +139,7 @@ func SetContractOwner(bs *state.BlockState, scs *state.ContractState, ownerState.AddBalance(nameState.Balance()) nameState.SubBalance(nameState.Balance()) + name := []byte(types.AergoName) if err = registerOwner(scs, name, rawaddr, name); err != nil { return nil, err } diff --git a/contract/name/name.go b/contract/name/name.go index 39e7efebb..6a8dc7a20 100644 --- a/contract/name/name.go +++ b/contract/name/name.go @@ -88,7 +88,7 @@ func Resolve(bs *state.BlockState, name []byte, legacy bool) ([]byte, error) { } func openContract(bs *state.BlockState) (*state.ContractState, error) { - v, err := bs.GetAccountStateV([]byte("aergo.name")) + v, err := bs.GetAccountStateV([]byte(types.AergoName)) if err != nil { return nil, err } diff --git a/contract/name/name_test.go b/contract/name/name_test.go index 2748dcdeb..4c6a5d274 100644 --- a/contract/name/name_test.go +++ b/contract/name/name_test.go @@ -45,13 +45,12 @@ func TestName(t *testing.T) { receiver, _ := sdb.GetStateDB().GetAccountStateV(tx.Recipient) bs := sdb.NewBlockState(sdb.GetRoot()) scs := openContractState(t, bs) - systemcs := openSystemContractState(t, bs) err := CreateName(scs, tx, sender, receiver, name) assert.NoError(t, err, "create name") scs = nextBlockContractState(t, bs, scs) - _, err = ValidateNameTx(tx, sender, scs, systemcs) + _, err = ValidateNameTx(tx, sender, scs) assert.Error(t, err, "same name") ret := getAddress(scs, []byte(name)) From 9d8d73234a57295befbe045acbadd18c76f7748d Mon Sep 17 00:00:00 2001 From: kch Date: Thu, 5 Oct 2023 06:09:03 +0000 Subject: [PATCH 14/22] remove system.InitGovernance() --- chain/chainhandle_test.go | 2 -- chain/chainservice.go | 1 - contract/name/execute.go | 3 +-- contract/name/name.go | 9 ++++----- contract/system/staking.go | 6 ------ contract/system/vote_test.go | 1 - contract/vm_dummy/vm_dummy.go | 1 - mempool/mempool.go | 6 +----- 8 files changed, 6 insertions(+), 23 deletions(-) diff --git a/chain/chainhandle_test.go b/chain/chainhandle_test.go index 531d59ded..852b8326d 100644 --- a/chain/chainhandle_test.go +++ b/chain/chainhandle_test.go @@ -13,7 +13,6 @@ import ( "github.com/aergoio/aergo-lib/db" "github.com/aergoio/aergo/v2/account/key" "github.com/aergoio/aergo/v2/contract" - "github.com/aergoio/aergo/v2/contract/system" "github.com/aergoio/aergo/v2/internal/common" "github.com/aergoio/aergo/v2/state" "github.com/aergoio/aergo/v2/types" @@ -37,7 +36,6 @@ func initTest(t *testing.T, testmode bool) { t.Fatalf("failed init : %s", err.Error()) } types.InitGovernance("dpos", true) - system.InitGovernance("dpos") } diff --git a/chain/chainservice.go b/chain/chainservice.go index f867b9d91..6a7d2e559 100644 --- a/chain/chainservice.go +++ b/chain/chainservice.go @@ -292,7 +292,6 @@ func NewChainService(cfg *cfg.Config) *ChainService { // For a strict governance transaction validation. types.InitGovernance(cs.ConsensusType(), cs.IsPublic()) - system.InitGovernance(cs.ConsensusType()) //reset parameter of aergo.system systemState, err := cs.SDB().GetSystemAccountState() diff --git a/contract/name/execute.go b/contract/name/execute.go index 9f88b9b63..6dc00e739 100644 --- a/contract/name/execute.go +++ b/contract/name/execute.go @@ -25,8 +25,7 @@ func ExecuteNameTx(bs *state.BlockState, scs *state.ContractState, txBody *types if bytes.Equal(sender.ID(), owner) { nameState = sender } else { - nameState, err = bs.GetAccountStateV(owner) - if err != nil { + if nameState, err = bs.GetAccountStateV(owner); err != nil { return nil, err } } diff --git a/contract/name/name.go b/contract/name/name.go index 6a8dc7a20..9fc8335cf 100644 --- a/contract/name/name.go +++ b/contract/name/name.go @@ -37,12 +37,13 @@ func createName(scs *state.ContractState, name []byte, owner []byte) error { // UpdateName is avaliable after bid implement func UpdateName(bs *state.BlockState, scs *state.ContractState, tx *types.TxBody, sender, receiver *state.V, name, to string) error { - amount := tx.GetAmountBigInt() if len(getAddress(scs, []byte(name))) <= types.NameLength { return fmt.Errorf("%s is not created yet", string(name)) } destination, _ := types.DecodeAddress(to) destination = GetAddress(scs, destination) + + amount := tx.GetAmountBigInt() sender.SubBalance(amount) receiver.AddBalance(amount) contract, err := bs.StateDB.OpenContractStateAccount(types.ToAccountID(destination)) @@ -101,8 +102,7 @@ func openContract(bs *state.BlockState) (*state.ContractState, error) { // GetAddress is resolve name for mempool func GetAddress(scs *state.ContractState, name []byte) []byte { - if len(name) == types.AddressLength || - types.IsSpecialAccount(name) { + if len(name) == types.AddressLength || types.IsSpecialAccount(name) { return name } return getAddress(scs, name) @@ -110,8 +110,7 @@ func GetAddress(scs *state.ContractState, name []byte) []byte { // GetAddressLegacy is resolve name for mempool by buggy logic, leaved for backward compatibility func GetAddressLegacy(scs *state.ContractState, name []byte) []byte { - if len(name) == types.AddressLength || - strings.Contains(string(name), ".") { + if len(name) == types.AddressLength || strings.Contains(string(name), ".") { return name } return getAddress(scs, name) diff --git a/contract/system/staking.go b/contract/system/staking.go index fec058c84..2422744f9 100644 --- a/contract/system/staking.go +++ b/contract/system/staking.go @@ -13,8 +13,6 @@ import ( "github.com/aergoio/aergo/v2/types" ) -var consensusType string - var ( stakingKey = []byte("staking") stakingTotalKey = []byte("stakingtotal") @@ -25,10 +23,6 @@ var ( const StakingDelay = 60 * 60 * 24 //block interval //const StakingDelay = 5 -func InitGovernance(consensus string) { - consensusType = consensus -} - type stakeCmd struct { *SystemContext amount *big.Int diff --git a/contract/system/vote_test.go b/contract/system/vote_test.go index 57b0562f4..8eff82f3b 100644 --- a/contract/system/vote_test.go +++ b/contract/system/vote_test.go @@ -35,7 +35,6 @@ func initTest(t *testing.T) (*state.ContractState, *state.V, *state.V) { t.Fatalf("failed init : %s", err.Error()) } // Need to pass the - InitGovernance("dpos") const testSender = "AmPNYHyzyh9zweLwDyuoiUuTVCdrdksxkRWDjVJS76WQLExa2Jr4" scs, err := bs.GetSystemAccountState() diff --git a/contract/vm_dummy/vm_dummy.go b/contract/vm_dummy/vm_dummy.go index 5de79b039..89f0c6bde 100644 --- a/contract/vm_dummy/vm_dummy.go +++ b/contract/vm_dummy/vm_dummy.go @@ -129,7 +129,6 @@ func LoadDummyChain(opts ...DummyChainOptions) (*DummyChain, error) { // To pass the governance tests. types.InitGovernance("dpos", true) - system.InitGovernance("dpos") // To pass dao parameters test scs, err := bc.sdb.GetStateDB().GetSystemAccountState() diff --git a/mempool/mempool.go b/mempool/mempool.go index 64bc9219f..9a4577301 100644 --- a/mempool/mempool.go +++ b/mempool/mempool.go @@ -676,15 +676,11 @@ func (mp *MemPool) validateTx(tx types.Transaction, account types.Address) error return err } case types.AergoName: - systemcs, err := mp.stateDB.GetSystemAccountState() - if err != nil { - return err - } sender, err := mp.stateDB.GetAccountStateV(account) if err != nil { return err } - if _, err := name.ValidateNameTx(tx.GetBody(), sender, scs, systemcs); err != nil { + if _, err := name.ValidateNameTx(tx.GetBody(), sender, scs); err != nil { return err } case types.AergoEnterprise: From e076259c06df38e7af2a4d729b2bd5d272f40258 Mon Sep 17 00:00:00 2001 From: kch Date: Thu, 5 Oct 2023 06:19:26 +0000 Subject: [PATCH 15/22] tidy make event code --- contract/system/staking.go | 34 ++++++++++++---------------------- contract/system/vote.go | 17 ++++++----------- 2 files changed, 18 insertions(+), 33 deletions(-) diff --git a/contract/system/staking.go b/contract/system/staking.go index 2422744f9..7b3956db7 100644 --- a/contract/system/staking.go +++ b/contract/system/staking.go @@ -55,23 +55,18 @@ func (c *stakeCmd) run() (*types.Event, error) { } sender.SubBalance(amount) receiver.AddBalance(amount) + + jsonArgs := "" if c.SystemContext.BlockInfo.ForkVersion < 2 { - return &types.Event{ - ContractAddress: receiver.ID(), - EventIdx: 0, - EventName: "stake", - JsonArgs: `{"who":"` + - types.EncodeAddress(sender.ID()) + - `", "amount":"` + amount.String() + `"}`, - }, nil + jsonArgs = `{"who":"` + types.EncodeAddress(sender.ID()) + `", "amount":"` + amount.String() + `"}` + } else { + jsonArgs = `["` + types.EncodeAddress(sender.ID()) + `", {"_bignum":"` + amount.String() + `"}]` } return &types.Event{ ContractAddress: receiver.ID(), EventIdx: 0, EventName: "stake", - JsonArgs: `["` + - types.EncodeAddress(sender.ID()) + - `", {"_bignum":"` + amount.String() + `"}]`, + JsonArgs: jsonArgs, }, nil } @@ -108,23 +103,18 @@ func (c *unstakeCmd) run() (*types.Event, error) { } sender.AddBalance(balanceAdjustment) receiver.SubBalance(balanceAdjustment) + + jsonArgs := "" if c.SystemContext.BlockInfo.ForkVersion < 2 { - return &types.Event{ - ContractAddress: receiver.ID(), - EventIdx: 0, - EventName: "unstake", - JsonArgs: `{"who":"` + - types.EncodeAddress(sender.ID()) + - `", "amount":"` + balanceAdjustment.String() + `"}`, - }, nil + jsonArgs = `{"who":"` + types.EncodeAddress(sender.ID()) + `", "amount":"` + balanceAdjustment.String() + `"}` + } else { + jsonArgs = `["` + types.EncodeAddress(sender.ID()) + `", {"_bignum":"` + balanceAdjustment.String() + `"}]` } return &types.Event{ ContractAddress: receiver.ID(), EventIdx: 0, EventName: "unstake", - JsonArgs: `["` + - types.EncodeAddress(sender.ID()) + - `", {"_bignum":"` + balanceAdjustment.String() + `"}]`, + JsonArgs: jsonArgs, }, nil } diff --git a/contract/system/vote.go b/contract/system/vote.go index bcdaeea6e..d859a982e 100644 --- a/contract/system/vote.go +++ b/contract/system/vote.go @@ -194,23 +194,18 @@ func (c *voteCmd) run() (*types.Event, error) { if err := c.updateVoteResult(); err != nil { return nil, err } + + jsonArgs := "" if c.SystemContext.BlockInfo.ForkVersion < 2 { - return &types.Event{ - ContractAddress: c.Receiver.ID(), - EventIdx: 0, - EventName: c.op.ID(), - JsonArgs: `{"who":"` + - types.EncodeAddress(c.txBody.Account) + - `", "vote":` + string(c.args) + `}`, - }, nil + jsonArgs = `{"who":"` + types.EncodeAddress(c.txBody.Account) + `", "vote":` + string(c.args) + `}` + } else { + jsonArgs = `["` + types.EncodeAddress(c.txBody.Account) + `", ` + string(c.args) + `]` } return &types.Event{ ContractAddress: c.Receiver.ID(), EventIdx: 0, EventName: c.op.ID(), - JsonArgs: `["` + - types.EncodeAddress(c.txBody.Account) + - `", ` + string(c.args) + `]`, + JsonArgs: jsonArgs, }, nil } From 9c9a79e650357e396889772e6782fb509dbe97a7 Mon Sep 17 00:00:00 2001 From: Bernardo Ramos Date: Fri, 13 Oct 2023 10:48:38 +0000 Subject: [PATCH 16/22] rename functions [skip ci] --- contract/system/execute_test.go | 4 ++-- contract/system/param.go | 24 ++++++++++++------------ contract/system/proposal_test.go | 6 +++--- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/contract/system/execute_test.go b/contract/system/execute_test.go index abe293f56..6f1f8acff 100644 --- a/contract/system/execute_test.go +++ b/contract/system/execute_test.go @@ -794,7 +794,7 @@ func TestProposalExecute2(t *testing.T) { // check the value for the current block assert.Equal(t, origGasPrice, GetGasPrice(), "result of gas price voting") // check the value for the next block - assert.Equal(t, balance0_5, GetNextParam("GASPRICE"), "result of gas price voting") + assert.Equal(t, balance0_5, GetNextBlockParam("GASPRICE"), "result of gas price voting") // commit the new value CommitParams(true) // check the value for the current block @@ -851,7 +851,7 @@ func TestProposalExecute2(t *testing.T) { // check the value for the current block assert.Equal(t, oldNamePrice, GetNamePrice(), "check name price") // check the value for the next block - assert.Equal(t, big.NewInt(1004), GetNextParam("NAMEPRICE"), "check name price") + assert.Equal(t, big.NewInt(1004), GetNextBlockParam("NAMEPRICE"), "check name price") // commit the new value CommitParams(true) // check the value for the current block diff --git a/contract/system/param.go b/contract/system/param.go index 07d8ad90b..b9375640b 100644 --- a/contract/system/param.go +++ b/contract/system/param.go @@ -22,25 +22,25 @@ func (p *parameters) setParam(proposalID string, value *big.Int) { } // save the new value for the param, to be active on the next block -func (p *parameters) setNextParam(proposalID string, value *big.Int) { +func (p *parameters) setNextBlockParam(proposalID string, value *big.Int) { p.mutex.Lock() defer p.mutex.Unlock() - p.params[nextParamKey(proposalID)] = value + p.params[nextBlockParamKey(proposalID)] = value } -func (p *parameters) delNextParam(proposalID string) { +func (p *parameters) delNextBlockParam(proposalID string) { p.mutex.Lock() defer p.mutex.Unlock() - delete(p.params, nextParamKey(proposalID)) + delete(p.params, nextBlockParamKey(proposalID)) } -func (p *parameters) getNextParam(proposalID string) *big.Int { +func (p *parameters) getNextBlockParam(proposalID string) *big.Int { p.mutex.Lock() defer p.mutex.Unlock() - return p.params[nextParamKey(proposalID)] + return p.params[nextBlockParamKey(proposalID)] } func (p *parameters) getParam(proposalID string) *big.Int { @@ -50,7 +50,7 @@ func (p *parameters) getParam(proposalID string) *big.Int { return p.params[proposalID] } -func nextParamKey(id string) string { +func nextBlockParamKey(id string) string { return id + "next" } @@ -132,7 +132,7 @@ func updateParam(s dataSetter, id string, value *big.Int) error { return err } // save the new value for the param, only active on the next block - systemParams.setNextParam(id, value) + systemParams.setNextBlockParam(id, value) return nil } @@ -141,21 +141,21 @@ func CommitParams(apply bool) { for i := sysParamIndex(0); i < sysParamMax; i++ { id := i.ID() // check if the param has a new value - if param := systemParams.getNextParam(id); param != nil { + if param := systemParams.getNextBlockParam(id); param != nil { if apply { // set the new value for the current block systemParams.setParam(id, param) } // delete the new value - systemParams.delNextParam(id) + systemParams.delNextBlockParam(id) } } } // get the param value for the next block -func GetNextParam(proposalID string) *big.Int { +func GetNextBlockParam(proposalID string) *big.Int { // check the value for the next block - if val := systemParams.getNextParam(proposalID); val != nil { + if val := systemParams.getNextBlockParam(proposalID); val != nil { return val } // check the value for the current block diff --git a/contract/system/proposal_test.go b/contract/system/proposal_test.go index c35ad1516..77365d114 100644 --- a/contract/system/proposal_test.go +++ b/contract/system/proposal_test.go @@ -127,7 +127,7 @@ func TestProposalBPCount(t *testing.T) { // check the value for the current block assert.Equal(t, 3, GetBpCount(), "check bp") // check the value for the next block - assert.Equal(t, big.NewInt(13), GetNextParam("BPCOUNT"), "check bp") + assert.Equal(t, big.NewInt(13), GetNextBlockParam("BPCOUNT"), "check bp") // commit the new value CommitParams(true) // check the value for the current block @@ -215,7 +215,7 @@ func TestFailProposals(t *testing.T) { // check the value for the current block assert.Equal(t, 3, GetBpCount(), "check bp") // check the value for the next block - assert.Equal(t, big.NewInt(13), GetNextParam("BPCOUNT"), "check bp") + assert.Equal(t, big.NewInt(13), GetNextBlockParam("BPCOUNT"), "check bp") // commit the new value CommitParams(true) // check the value for the current block @@ -245,7 +245,7 @@ func TestFailProposals(t *testing.T) { // check the value for the current block assert.Equal(t, oldGasPrice, GetGasPrice(), "check gas price") // check the value for the next block - assert.Equal(t, big.NewInt(101), GetNextParam("GASPRICE"), "check gas price") + assert.Equal(t, big.NewInt(101), GetNextBlockParam("GASPRICE"), "check gas price") // commit the new value CommitParams(true) // check the value for the current block From 9b0c212e357e3c182d7438507b6c0eb75f7910e1 Mon Sep 17 00:00:00 2001 From: Bernardo Ramos Date: Mon, 16 Oct 2023 14:30:34 +0000 Subject: [PATCH 17/22] add integration tests for dpos and raft --- tests/bp01.id | 1 + tests/bp01.key | 1 + tests/bp01.pub | Bin 0 -> 37 bytes tests/bp02.id | 1 + tests/bp02.key | 2 + tests/bp02.pub | 1 + tests/bp03.id | 1 + tests/bp03.key | 1 + tests/bp03.pub | 1 + tests/common.sh | 42 +++++++++- tests/config-node1.toml | 51 ++++++++++++ tests/config-node2.toml | 51 ++++++++++++ tests/config-node3.toml | 51 ++++++++++++ tests/{config.toml => config-sbp.toml} | 0 tests/genesis-dpos.json | 17 ++++ tests/genesis-raft.json | 31 ++++++++ tests/run_tests.sh | 106 ++++++++++++++++++------- tests/test-brick.sh | 1 - 18 files changed, 328 insertions(+), 31 deletions(-) create mode 100644 tests/bp01.id create mode 100644 tests/bp01.key create mode 100644 tests/bp01.pub create mode 100644 tests/bp02.id create mode 100644 tests/bp02.key create mode 100644 tests/bp02.pub create mode 100644 tests/bp03.id create mode 100644 tests/bp03.key create mode 100644 tests/bp03.pub create mode 100644 tests/config-node1.toml create mode 100644 tests/config-node2.toml create mode 100644 tests/config-node3.toml rename tests/{config.toml => config-sbp.toml} (100%) create mode 100644 tests/genesis-dpos.json create mode 100644 tests/genesis-raft.json delete mode 100755 tests/test-brick.sh diff --git a/tests/bp01.id b/tests/bp01.id new file mode 100644 index 000000000..e6b88a555 --- /dev/null +++ b/tests/bp01.id @@ -0,0 +1 @@ +16Uiu2HAmG4PSXYUxkPbNb7qTcEExFpgAwBrm3hB32aJXuvX2f1sd \ No newline at end of file diff --git a/tests/bp01.key b/tests/bp01.key new file mode 100644 index 000000000..8ab66a8aa --- /dev/null +++ b/tests/bp01.key @@ -0,0 +1 @@ + A<��iT�B-:�1J �\�G��1�� T'�� \ No newline at end of file diff --git a/tests/bp01.pub b/tests/bp01.pub new file mode 100644 index 0000000000000000000000000000000000000000..d428339551b9ee5a497c99c1d02f38529dda9dc1 GIT binary patch literal 37 tcmd;J5>jL~n%FLSbcTU@>0_7Yw_laW_}SH%Z2s7nb-PA-CqqX_1po*T52FA8 literal 0 HcmV?d00001 diff --git a/tests/bp02.id b/tests/bp02.id new file mode 100644 index 000000000..102b8a198 --- /dev/null +++ b/tests/bp02.id @@ -0,0 +1 @@ +16Uiu2HAmMzncFmnpjigZJRoraToKkABvZimMUAyXf6bdrZeN7mbJ \ No newline at end of file diff --git a/tests/bp02.key b/tests/bp02.key new file mode 100644 index 000000000..9c9f8c626 --- /dev/null +++ b/tests/bp02.key @@ -0,0 +1,2 @@ + �5 +&���d�f�#[k��1~� �Ľ�=�� \ No newline at end of file diff --git a/tests/bp02.pub b/tests/bp02.pub new file mode 100644 index 000000000..f9627f3fc --- /dev/null +++ b/tests/bp02.pub @@ -0,0 +1 @@ +!�˅����:^�p�B�X̾����2/���~� \ No newline at end of file diff --git a/tests/bp03.id b/tests/bp03.id new file mode 100644 index 000000000..ce5e264a5 --- /dev/null +++ b/tests/bp03.id @@ -0,0 +1 @@ +16Uiu2HAmKB7RYXe1uHNYMtkuuM2fEHxsv6P9PZ45ogJw6aZD3y7x \ No newline at end of file diff --git a/tests/bp03.key b/tests/bp03.key new file mode 100644 index 000000000..769f934f5 --- /dev/null +++ b/tests/bp03.key @@ -0,0 +1 @@ + ⧾o�{V�IԖu�Q���7��6$M���p�G� \ No newline at end of file diff --git a/tests/bp03.pub b/tests/bp03.pub new file mode 100644 index 000000000..8704fcc3d --- /dev/null +++ b/tests/bp03.pub @@ -0,0 +1 @@ +!`݋/�|t�i��+�յ͚��B�5mHK4[EC \ No newline at end of file diff --git a/tests/common.sh b/tests/common.sh index bd5abe899..e98d2024e 100644 --- a/tests/common.sh +++ b/tests/common.sh @@ -1,4 +1,44 @@ +start_nodes() { + + if [ "$consensus" == "sbp" ]; then + # open the aergo node in testmode + ../bin/aergosvr --testmode --home ./aergo-files > logs 2> logs & + pid=$! + else + # open the 3 nodes + ../bin/aergosvr --home ./node1 >> logs1 2>> logs1 & + pid1=$! + ../bin/aergosvr --home ./node2 >> logs2 2>> logs2 & + pid2=$! + ../bin/aergosvr --home ./node3 >> logs3 2>> logs3 & + pid3=$! + fi + + # wait the node(s) to be ready + if [ "$consensus" == "sbp" ]; then + sleep 3 + elif [ "$consensus" == "dpos" ]; then + sleep 5 + elif [ "$consensus" == "raft" ]; then + sleep 2 + fi + +} + +stop_nodes() { + + if [ "$consensus" == "sbp" ]; then + kill $pid + else + kill $pid1 $pid2 $pid3 + #kill $pid1 + #kill $pid2 + #kill $pid3 + fi + +} + get_deploy_args() { contract_file=$1 @@ -27,7 +67,7 @@ get_receipt() { set +e while true; do - output=$(../bin/aergocli receipt get $txhash 2>&1 > receipt.json) + output=$(../bin/aergocli receipt get --port $query_port $txhash 2>&1 > receipt.json) #echo "output: $output" diff --git a/tests/config-node1.toml b/tests/config-node1.toml new file mode 100644 index 000000000..7e259713c --- /dev/null +++ b/tests/config-node1.toml @@ -0,0 +1,51 @@ +# aergo TOML Configuration File (https://github.com/toml-lang/toml) +# base configurations +#datadir = "./data" +enableprofile = true +profileport = 6060 + +[rpc] +netserviceaddr = "0.0.0.0" +netserviceport = 7845 +netservicetrace = false +nstls = false +nscert = "" +nskey = "" +nsallowcors = false + +[p2p] +netprotocoladdr = "127.0.0.1" +netprotocolport = 2001 +npbindaddr = "0.0.0.0" +npbindport = 2001 +nptls = false +npcert = "" +npkey = "bp01.key" +npaddpeers = [ +#"/ip4/127.0.0.1/tcp/2001/p2p/16Uiu2HAmG4PSXYUxkPbNb7qTcEExFpgAwBrm3hB32aJXuvX2f1sd", +"/ip4/127.0.0.1/tcp/2002/p2p/16Uiu2HAmMzncFmnpjigZJRoraToKkABvZimMUAyXf6bdrZeN7mbJ", +"/ip4/127.0.0.1/tcp/2003/p2p/16Uiu2HAmKB7RYXe1uHNYMtkuuM2fEHxsv6P9PZ45ogJw6aZD3y7x" +] +npexposeself = false +npdiscoverpeers = false +npusepolaris = false +peerrole = "producer" + +[blockchain] +maxblocksize = 1000000 + +[mempool] +showmetrics = false +#dumpfilepath ="./data1/mempool.dump" + +[consensus] +enablebp = true + +[consensus.raft] +newcluster=true +name="bp01" + +[hardfork] +v2 = "0" +v3 = "10000" +v4 = "10000" diff --git a/tests/config-node2.toml b/tests/config-node2.toml new file mode 100644 index 000000000..f253c8dbd --- /dev/null +++ b/tests/config-node2.toml @@ -0,0 +1,51 @@ +# aergo TOML Configuration File (https://github.com/toml-lang/toml) +# base configurations +#datadir = "./data" +enableprofile = true +profileport = 6060 + +[rpc] +netserviceaddr = "0.0.0.0" +netserviceport = 8845 +netservicetrace = false +nstls = false +nscert = "" +nskey = "" +nsallowcors = false + +[p2p] +netprotocoladdr = "127.0.0.1" +netprotocolport = 2002 +npbindaddr = "0.0.0.0" +npbindport = 2002 +nptls = false +npcert = "" +npkey = "bp02.key" +npaddpeers = [ +"/ip4/127.0.0.1/tcp/2001/p2p/16Uiu2HAmG4PSXYUxkPbNb7qTcEExFpgAwBrm3hB32aJXuvX2f1sd", +#"/ip4/127.0.0.1/tcp/2002/p2p/16Uiu2HAmMzncFmnpjigZJRoraToKkABvZimMUAyXf6bdrZeN7mbJ", +"/ip4/127.0.0.1/tcp/2003/p2p/16Uiu2HAmKB7RYXe1uHNYMtkuuM2fEHxsv6P9PZ45ogJw6aZD3y7x" +] +npexposeself = false +npdiscoverpeers = false +npusepolaris = false +peerrole = "producer" + +[blockchain] +maxblocksize = 1000000 + +[mempool] +showmetrics = false +#dumpfilepath ="./data1/mempool.dump" + +[consensus] +enablebp = true + +[consensus.raft] +newcluster=true +name="bp02" + +[hardfork] +v2 = "0" +v3 = "10000" +v4 = "10000" diff --git a/tests/config-node3.toml b/tests/config-node3.toml new file mode 100644 index 000000000..b4588f84b --- /dev/null +++ b/tests/config-node3.toml @@ -0,0 +1,51 @@ +# aergo TOML Configuration File (https://github.com/toml-lang/toml) +# base configurations +#datadir = "./data" +enableprofile = true +profileport = 6060 + +[rpc] +netserviceaddr = "0.0.0.0" +netserviceport = 9845 +netservicetrace = false +nstls = false +nscert = "" +nskey = "" +nsallowcors = false + +[p2p] +netprotocoladdr = "127.0.0.1" +netprotocolport = 2003 +npbindaddr = "0.0.0.0" +npbindport = 2003 +nptls = false +npcert = "" +npkey = "bp03.key" +npaddpeers = [ +"/ip4/127.0.0.1/tcp/2001/p2p/16Uiu2HAmG4PSXYUxkPbNb7qTcEExFpgAwBrm3hB32aJXuvX2f1sd", +"/ip4/127.0.0.1/tcp/2002/p2p/16Uiu2HAmMzncFmnpjigZJRoraToKkABvZimMUAyXf6bdrZeN7mbJ" +#"/ip4/127.0.0.1/tcp/2003/p2p/16Uiu2HAmKB7RYXe1uHNYMtkuuM2fEHxsv6P9PZ45ogJw6aZD3y7x" +] +npexposeself = false +npdiscoverpeers = false +npusepolaris = false +peerrole = "producer" + +[blockchain] +maxblocksize = 1000000 + +[mempool] +showmetrics = false +#dumpfilepath ="./data1/mempool.dump" + +[consensus] +enablebp = true + +[consensus.raft] +newcluster=true +name="bp03" + +[hardfork] +v2 = "0" +v3 = "10000" +v4 = "10000" diff --git a/tests/config.toml b/tests/config-sbp.toml similarity index 100% rename from tests/config.toml rename to tests/config-sbp.toml diff --git a/tests/genesis-dpos.json b/tests/genesis-dpos.json new file mode 100644 index 000000000..da860252f --- /dev/null +++ b/tests/genesis-dpos.json @@ -0,0 +1,17 @@ +{ + "chain_id":{ + "magic":"test.chain", + "public":true, + "mainnet":false, + "consensus":"dpos" + }, + "timestamp": 1559883600000000000, + "balance": { + "AmPpcKvToDCUkhT1FJjdbNvR4kNDhLFJGHkSqfjWe3QmHm96qv4R": "1000000000000000000000" + }, + "bps": [ + "16Uiu2HAmG4PSXYUxkPbNb7qTcEExFpgAwBrm3hB32aJXuvX2f1sd", + "16Uiu2HAmMzncFmnpjigZJRoraToKkABvZimMUAyXf6bdrZeN7mbJ", + "16Uiu2HAmKB7RYXe1uHNYMtkuuM2fEHxsv6P9PZ45ogJw6aZD3y7x" + ] +} diff --git a/tests/genesis-raft.json b/tests/genesis-raft.json new file mode 100644 index 000000000..c996b3590 --- /dev/null +++ b/tests/genesis-raft.json @@ -0,0 +1,31 @@ +{ + "chain_id":{ + "magic":"test.chain", + "public":true, + "mainnet":false, + "consensus":"raft" + }, + "timestamp": 1559883600000000000, + "balance": { + "AmPpcKvToDCUkhT1FJjdbNvR4kNDhLFJGHkSqfjWe3QmHm96qv4R": "1000000000000000000000" + }, + "bps": [ + ], + "enterprise_bps": [ + { + "name": "bp01", + "address": "/ip4/127.0.0.1/tcp/2001", + "peerid": "16Uiu2HAmG4PSXYUxkPbNb7qTcEExFpgAwBrm3hB32aJXuvX2f1sd" + }, + { + "name": "bp02", + "address": "/ip4/127.0.0.1/tcp/2002", + "peerid": "16Uiu2HAmMzncFmnpjigZJRoraToKkABvZimMUAyXf6bdrZeN7mbJ" + }, + { + "name": "bp03", + "address": "/ip4/127.0.0.1/tcp/2003", + "peerid": "16Uiu2HAmKB7RYXe1uHNYMtkuuM2fEHxsv6P9PZ45ogJw6aZD3y7x" + } + ] +} diff --git a/tests/run_tests.sh b/tests/run_tests.sh index 0089ec715..83413a346 100755 --- a/tests/run_tests.sh +++ b/tests/run_tests.sh @@ -1,23 +1,72 @@ # stop on errors set -e +source common.sh -# run the brick test -./test-brick.sh +arg=$1 +if [ "$arg" != "sbp" ] && [ "$arg" != "dpos" ] && [ "$arg" != "raft" ] && [ "$arg" != "brick" ]; then + echo "Usage: $0 [brick|sbp|dpos|raft]" + exit 1 +fi +echo "Running integration tests for $arg" + +if [ "$arg" == "brick" ]; then + # run the brick test + ../bin/brick -V test.brick + exit 0 +fi + +consensus=$arg + +if [ "$consensus" == "sbp" ]; then + # delete and recreate the aergo folder + rm -rf ./aergo-files + mkdir aergo-files + # copy the config file + cp config-sbp.toml ./aergo-files/config.toml + # delete the old logs + rm -f logs +else + # delete and recreate the aergo folder + rm -rf node1 + rm -rf node2 + rm -rf node3 + mkdir node1 + mkdir node2 + mkdir node3 + # copy the config files + cp config-node1.toml node1/config.toml + cp config-node2.toml node2/config.toml + cp config-node3.toml node3/config.toml + # delete the old logs + rm -f logs1 logs2 logs3 + # create the genesis block + echo "creating genesis block..." + ../bin/aergosvr init --genesis ./genesis-$consensus.json --home ./node1 + ../bin/aergosvr init --genesis ./genesis-$consensus.json --home ./node2 + ../bin/aergosvr init --genesis ./genesis-$consensus.json --home ./node3 +fi -# delete and recreate the aergo folder -rm -rf ./aergo-files -mkdir aergo-files -# copy the config file -cp config.toml ./aergo-files/ +# define the config files according to the consensus +if [ "$consensus" == "sbp" ]; then + config_files=("./aergo-files/config.toml") +elif [ "$consensus" == "dpos" ]; then + config_files=("./node1/config.toml" "./node2/config.toml" "./node3/config.toml") +elif [ "$consensus" == "raft" ]; then + config_files=("./node1/config.toml" "./node2/config.toml" "./node3/config.toml") +fi + +# define which port used for queries +if [ "$consensus" == "sbp" ]; then + query_port="7845" +else + query_port="9845" +fi -# open the aergo server in testmode to create the config file echo "" -echo "starting the aergo server..." -../bin/aergosvr --testmode --home ./aergo-files > logs 2> logs & -pid=$! -# wait it to be ready -sleep 2 +echo "starting nodes..." +start_nodes +# get the current hardfork version version=$(../bin/aergocli blockchain | jq .ChainInfo.Chainid.Version | sed 's/"//g') function set_version() { @@ -31,21 +80,16 @@ function set_version() { block_no=$(../bin/aergocli blockchain | jq .Height | sed 's/"//g') # increment 2 numbers block_no=$((block_no+2)) - # terminate the server process - kill $pid - # save the hardfork config on the config file - echo "updating the config file..." - if [ $version -eq 2 ]; then - sed -i "s/^v2 = \"10000\"$/v2 = \"${block_no}\"/" ./aergo-files/config.toml - elif [ $version -eq 3 ]; then - sed -i "s/^v3 = \"10000\"$/v3 = \"${block_no}\"/" ./aergo-files/config.toml - fi + # terminate the server process(es) + stop_nodes + # save the hardfork config on the config file(s) + echo "updating the config file(s)..." + for config_file in "${config_files[@]}"; do + sed -i "s/^v$version = \"10000\"$/v$version = \"${block_no}\"/" $config_file + done # restart the aergo server - echo "restarting the aergo server..." - ../bin/aergosvr --testmode --home ./aergo-files > logs 2> logs & - pid=$! - # wait it to be ready - sleep 3 + echo "restarting the aergo nodes..." + start_nodes # check if it worked new_version=$(../bin/aergocli blockchain | jq .ChainInfo.Chainid.Version | sed 's/"//g') if [ $new_version -ne $version ]; then @@ -77,6 +121,10 @@ function check() { fi } +# make these variables accessible to the called scripts +export consensus +export query_port + # create the account used on tests echo "creating user account..." ../bin/aergocli account import --keystore . --if 47zh1byk8MqWkQo5y8dvbrex99ZMdgZqfydar7w2QQgQqc7YrmFsBuMeF1uHWa5TwA1ZwQ7V6 --password bmttest @@ -103,9 +151,9 @@ check ./test-contract-deploy.sh # terminate the server process echo "" -echo "closing the aergo server" +echo "closing the aergo nodes" echo "" -kill $pid +stop_nodes # print the summary if [ $num_failed_tests -gt 0 ]; then diff --git a/tests/test-brick.sh b/tests/test-brick.sh deleted file mode 100755 index 155dd32c6..000000000 --- a/tests/test-brick.sh +++ /dev/null @@ -1 +0,0 @@ -../bin/brick -V test.brick From b260067a8857eff2d21f52dfd1b3ade5a6dbebb1 Mon Sep 17 00:00:00 2001 From: Bernardo Ramos Date: Mon, 16 Oct 2023 14:32:35 +0000 Subject: [PATCH 18/22] run all integration tests on CI --- .github/workflows/full_test.yml | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/.github/workflows/full_test.yml b/.github/workflows/full_test.yml index add285e1b..d34d0cbdb 100644 --- a/.github/workflows/full_test.yml +++ b/.github/workflows/full_test.yml @@ -61,9 +61,8 @@ jobs: - name: Integration Tests run: | - if [ -d "tests" ]; then - cd tests - ./run_tests.sh - else - echo "The 'tests' folder does not exist." - fi + cd tests + ./run_tests.sh brick + ./run_tests.sh sbp + ./run_tests.sh dpos + ./run_tests.sh raft From 6f6c90e040d2f90120c5d93c412516c11b62e563 Mon Sep 17 00:00:00 2001 From: Bernardo Ramos Date: Mon, 16 Oct 2023 15:53:38 +0000 Subject: [PATCH 19/22] fix test-gas-per-function for dpos and raft --- .../vm_dummy/test_files/gas_per_function.lua | 4 ++-- contract/vm_dummy/vm_dummy_pub_test.go | 4 ++-- tests/test-gas-per-function-v2.sh | 21 +++++++++++++++++-- tests/test-gas-per-function-v3.sh | 21 +++++++++++++++++-- 4 files changed, 42 insertions(+), 8 deletions(-) diff --git a/contract/vm_dummy/test_files/gas_per_function.lua b/contract/vm_dummy/test_files/gas_per_function.lua index 3b27a8192..bd1bf0be4 100644 --- a/contract/vm_dummy/test_files/gas_per_function.lua +++ b/contract/vm_dummy/test_files/gas_per_function.lua @@ -1286,9 +1286,9 @@ function run_test(function_name, ...) end -function deposit() +function default() -- do nothing, only receive native aergo tokens end abi.register(run_test) -abi.payable(deposit) +abi.payable(default) diff --git a/contract/vm_dummy/vm_dummy_pub_test.go b/contract/vm_dummy/vm_dummy_pub_test.go index 988f6d8a4..2ca84e678 100644 --- a/contract/vm_dummy/vm_dummy_pub_test.go +++ b/contract/vm_dummy/vm_dummy_pub_test.go @@ -81,8 +81,8 @@ func TestGasPerFunction(t *testing.T) { // transfer funds to the contracts err = bc.ConnectBlock( - NewLuaTxCall("user", "contract_v2", uint64(10e18), `{"Name":"deposit"}`), - NewLuaTxCall("user", "contract_v3", uint64(10e18), `{"Name":"deposit"}`), + NewLuaTxCall("user", "contract_v2", uint64(10e18), `{"Name":"default"}`), + NewLuaTxCall("user", "contract_v3", uint64(10e18), `{"Name":"default"}`), ) assert.NoError(t, err, "sending funds to contracts") diff --git a/tests/test-gas-per-function-v2.sh b/tests/test-gas-per-function-v2.sh index 3fd16a4a8..40091b577 100755 --- a/tests/test-gas-per-function-v2.sh +++ b/tests/test-gas-per-function-v2.sh @@ -16,9 +16,26 @@ address=$(cat receipt.json | jq .contractAddress | sed 's/"//g') assert_equals "$status" "CREATED" +echo "-- transfer funds to the contract --" + +from=AmPpcKvToDCUkhT1FJjdbNvR4kNDhLFJGHkSqfjWe3QmHm96qv4R + +txhash=$(../bin/aergocli --keystore . --password bmttest \ + sendtx --from $from --to $address --amount 5aergo \ + | jq .hash | sed 's/"//g') + +get_receipt $txhash + +status=$(cat receipt.json | jq .status | sed 's/"//g') +ret=$(cat receipt.json | jq .ret | sed 's/"//g') + +assert_equals "$status" "SUCCESS" +assert_equals "$ret" "{}" + + echo "-- get account's nonce --" -account_state=$(../bin/aergocli getstate --address AmPpcKvToDCUkhT1FJjdbNvR4kNDhLFJGHkSqfjWe3QmHm96qv4R) +account_state=$(../bin/aergocli getstate --address $from) nonce=$(echo $account_state | jq .nonce | sed 's/"//g') @@ -141,7 +158,7 @@ add_test "system.getCreator" 135156 add_test "system.getOrigin" 135656 add_test "contract.send" 135716 -add_test "contract.balance" 135797 +#add_test "contract.balance" 135797 add_test "contract.deploy" 158752 add_test "contract.call" 149642 add_test "contract.pcall" 150563 diff --git a/tests/test-gas-per-function-v3.sh b/tests/test-gas-per-function-v3.sh index abe5ad2ee..35c39caff 100755 --- a/tests/test-gas-per-function-v3.sh +++ b/tests/test-gas-per-function-v3.sh @@ -16,9 +16,26 @@ address=$(cat receipt.json | jq .contractAddress | sed 's/"//g') assert_equals "$status" "CREATED" +echo "-- transfer funds to the contract --" + +from=AmPpcKvToDCUkhT1FJjdbNvR4kNDhLFJGHkSqfjWe3QmHm96qv4R + +txhash=$(../bin/aergocli --keystore . --password bmttest \ + sendtx --from $from --to $address --amount 5aergo \ + | jq .hash | sed 's/"//g') + +get_receipt $txhash + +status=$(cat receipt.json | jq .status | sed 's/"//g') +ret=$(cat receipt.json | jq .ret | sed 's/"//g') + +assert_equals "$status" "SUCCESS" +assert_equals "$ret" "{}" + + echo "-- get account's nonce --" -account_state=$(../bin/aergocli getstate --address AmPpcKvToDCUkhT1FJjdbNvR4kNDhLFJGHkSqfjWe3QmHm96qv4R) +account_state=$(../bin/aergocli getstate --address $from) nonce=$(echo $account_state | jq .nonce | sed 's/"//g') @@ -141,7 +158,7 @@ add_test "system.getCreator" 135156 add_test "system.getOrigin" 135656 add_test "contract.send" 135716 -add_test "contract.balance" 135797 +#add_test "contract.balance" 135797 add_test "contract.deploy" 158752 add_test "contract.call" 149642 add_test "contract.pcall" 150563 From ef08e061d5e61856f49acfd28cc48e366d80e562 Mon Sep 17 00:00:00 2001 From: Bernardo Ramos Date: Mon, 16 Oct 2023 16:07:06 +0000 Subject: [PATCH 20/22] separate integration tests on CI --- .github/workflows/full_test.yml | 18 +++++++++++------- tests/common.sh | 3 --- tests/config-node1.toml | 5 +---- tests/config-node2.toml | 5 +---- tests/config-node3.toml | 5 +---- 5 files changed, 14 insertions(+), 22 deletions(-) diff --git a/.github/workflows/full_test.yml b/.github/workflows/full_test.yml index d34d0cbdb..8bb987af7 100644 --- a/.github/workflows/full_test.yml +++ b/.github/workflows/full_test.yml @@ -59,10 +59,14 @@ jobs: if: github.event_name != 'push' || github.ref_name != 'master' || github.ref_type != 'branch' run: go test -timeout 999s -v ./... - - name: Integration Tests - run: | - cd tests - ./run_tests.sh brick - ./run_tests.sh sbp - ./run_tests.sh dpos - ./run_tests.sh raft + - name: Integration Tests - brick + run: cd tests && ./run_tests.sh brick + + - name: Integration Tests - sbp + run: cd tests && ./run_tests.sh sbp + + - name: Integration Tests - dpos + run: cd tests && ./run_tests.sh dpos + + - name: Integration Tests - raft + run: cd tests && ./run_tests.sh raft diff --git a/tests/common.sh b/tests/common.sh index e98d2024e..6cd82200c 100644 --- a/tests/common.sh +++ b/tests/common.sh @@ -32,9 +32,6 @@ stop_nodes() { kill $pid else kill $pid1 $pid2 $pid3 - #kill $pid1 - #kill $pid2 - #kill $pid3 fi } diff --git a/tests/config-node1.toml b/tests/config-node1.toml index 7e259713c..8ffb68f7e 100644 --- a/tests/config-node1.toml +++ b/tests/config-node1.toml @@ -1,8 +1,6 @@ # aergo TOML Configuration File (https://github.com/toml-lang/toml) # base configurations -#datadir = "./data" -enableprofile = true -profileport = 6060 +enableprofile = false [rpc] netserviceaddr = "0.0.0.0" @@ -36,7 +34,6 @@ maxblocksize = 1000000 [mempool] showmetrics = false -#dumpfilepath ="./data1/mempool.dump" [consensus] enablebp = true diff --git a/tests/config-node2.toml b/tests/config-node2.toml index f253c8dbd..f68988e37 100644 --- a/tests/config-node2.toml +++ b/tests/config-node2.toml @@ -1,8 +1,6 @@ # aergo TOML Configuration File (https://github.com/toml-lang/toml) # base configurations -#datadir = "./data" -enableprofile = true -profileport = 6060 +enableprofile = false [rpc] netserviceaddr = "0.0.0.0" @@ -36,7 +34,6 @@ maxblocksize = 1000000 [mempool] showmetrics = false -#dumpfilepath ="./data1/mempool.dump" [consensus] enablebp = true diff --git a/tests/config-node3.toml b/tests/config-node3.toml index b4588f84b..888aca265 100644 --- a/tests/config-node3.toml +++ b/tests/config-node3.toml @@ -1,8 +1,6 @@ # aergo TOML Configuration File (https://github.com/toml-lang/toml) # base configurations -#datadir = "./data" -enableprofile = true -profileport = 6060 +enableprofile = false [rpc] netserviceaddr = "0.0.0.0" @@ -36,7 +34,6 @@ maxblocksize = 1000000 [mempool] showmetrics = false -#dumpfilepath ="./data1/mempool.dump" [consensus] enablebp = true From 13d25fe2dea3114c773c36319637f0ec5df36e8e Mon Sep 17 00:00:00 2001 From: Hayarobi Park Date: Mon, 16 Oct 2023 19:08:10 +0900 Subject: [PATCH 21/22] Fix wrong block interval in raft consensus and sbp --- consensus/impl/raftv2/blockfactory.go | 3 ++- consensus/impl/sbp/sbp.go | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/consensus/impl/raftv2/blockfactory.go b/consensus/impl/raftv2/blockfactory.go index 9254ff4fb..55b0baf67 100644 --- a/consensus/impl/raftv2/blockfactory.go +++ b/consensus/impl/raftv2/blockfactory.go @@ -237,7 +237,7 @@ func (bf *BlockFactory) Ticker() *time.Ticker { return time.NewTicker(BlockFactoryTickMs) } -// QueueJob send a block triggering information to jq. +// QueueJob send a block triggering information to jq, and hold to wait func (bf *BlockFactory) QueueJob(now time.Time, jq chan<- interface{}) { bf.jobLock.Lock() defer bf.jobLock.Unlock() @@ -279,6 +279,7 @@ func (bf *BlockFactory) QueueJob(now time.Time, jq chan<- interface{}) { logger.Debug().Str("work", work.ToString()).Str("prev", prevToString(prev)).Msg("new work generated") jq <- work + time.Sleep(BlockIntervalMs) } } diff --git a/consensus/impl/sbp/sbp.go b/consensus/impl/sbp/sbp.go index 41e83c69c..a8ef44cc0 100644 --- a/consensus/impl/sbp/sbp.go +++ b/consensus/impl/sbp/sbp.go @@ -45,7 +45,7 @@ func (te *txExec) Apply(bState *state.BlockState, tx types.Transaction) error { return err } -// SimpleBlockFactory implments a simple block factory which generate block each cfg.Consensus.BlockInterval. +// SimpleBlockFactory implements a simple block factory which generate block each cfg.Consensus.BlockInterval. // // This can be used for testing purpose. type SimpleBlockFactory struct { @@ -118,6 +118,7 @@ func (s *SimpleBlockFactory) QueueJob(now time.Time, jq chan<- interface{}) { } s.prevBlock = b jq <- b + time.Sleep(s.blockInterval) } } From ba91621fbdadee47bddfb1334f4680125a8ac34b Mon Sep 17 00:00:00 2001 From: Hayarobi Park Date: Tue, 17 Oct 2023 10:00:26 +0900 Subject: [PATCH 22/22] Improve comments --- consensus/consensus.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/consensus/consensus.go b/consensus/consensus.go index 656c446cc..8d77a4b12 100644 --- a/consensus/consensus.go +++ b/consensus/consensus.go @@ -69,6 +69,8 @@ type Consensus interface { ChainConsensus ConsensusAccessor Ticker() *time.Ticker + // QueueJob queues block generation job. + // It waits until next block generation time is reached in raft consensus and sbp. QueueJob(now time.Time, jq chan<- interface{}) BlockFactory() BlockFactory QuitChan() chan interface{}