aboutsummaryrefslogtreecommitdiffstats
path: root/core/vm/governance_test.go
diff options
context:
space:
mode:
authorWei-Ning Huang <w@dexon.org>2018-11-19 14:36:36 +0800
committerWei-Ning Huang <w@byzantine-lab.io>2019-06-12 17:27:18 +0800
commit78dac82d810fe4a1ad6878adbc789f909155f472 (patch)
tree13189c293ed8603a7e9d8b15571fff1737c9bc1f /core/vm/governance_test.go
parent8a0b917def2d80b112d7d8a5854aba62afc0a630 (diff)
downloadgo-tangerine-78dac82d810fe4a1ad6878adbc789f909155f472.tar
go-tangerine-78dac82d810fe4a1ad6878adbc789f909155f472.tar.gz
go-tangerine-78dac82d810fe4a1ad6878adbc789f909155f472.tar.bz2
go-tangerine-78dac82d810fe4a1ad6878adbc789f909155f472.tar.lz
go-tangerine-78dac82d810fe4a1ad6878adbc789f909155f472.tar.xz
go-tangerine-78dac82d810fe4a1ad6878adbc789f909155f472.tar.zst
go-tangerine-78dac82d810fe4a1ad6878adbc789f909155f472.zip
governance: implement delegate/undelegate function and add tests (#33)
Implement delegate/undelegate function to allow others to delegate it's fund to stake on a node. Also added governance contract tests.
Diffstat (limited to 'core/vm/governance_test.go')
-rw-r--r--core/vm/governance_test.go557
1 files changed, 557 insertions, 0 deletions
diff --git a/core/vm/governance_test.go b/core/vm/governance_test.go
index ebdca7fd8..7718e99d2 100644
--- a/core/vm/governance_test.go
+++ b/core/vm/governance_test.go
@@ -19,6 +19,7 @@ package vm
import (
"bytes"
+ "crypto/ecdsa"
"math/big"
"math/rand"
"testing"
@@ -26,7 +27,9 @@ import (
"github.com/dexon-foundation/dexon/common"
"github.com/dexon-foundation/dexon/core/state"
+ "github.com/dexon-foundation/dexon/crypto"
"github.com/dexon-foundation/dexon/ethdb"
+ "github.com/dexon-foundation/dexon/params"
"github.com/stretchr/testify/suite"
)
@@ -79,3 +82,557 @@ func (g *GovernanceStateHelperTestSuite) TestReadWriteBytes() {
func TestGovernanceStateHelper(t *testing.T) {
suite.Run(t, new(GovernanceStateHelperTestSuite))
}
+
+type GovernanceContractTestSuite struct {
+ suite.Suite
+
+ config *params.DexconConfig
+ memDB *ethdb.MemDatabase
+ stateDB *state.StateDB
+ s *GovernanceStateHelper
+}
+
+func (g *GovernanceContractTestSuite) SetupTest() {
+ memDB := ethdb.NewMemDatabase()
+ stateDB, err := state.New(common.Hash{}, state.NewDatabase(memDB))
+ if err != nil {
+ panic(err)
+ }
+ g.memDB = memDB
+ g.stateDB = stateDB
+ g.s = &GovernanceStateHelper{stateDB}
+
+ config := params.TestnetChainConfig.Dexcon
+ g.config = config
+
+ // Give governance contract balance so it will not be deleted because of being an empty state object.
+ stateDB.AddBalance(GovernanceContractAddress, big.NewInt(1))
+
+ // Genesis CRS.
+ crs := crypto.Keccak256Hash([]byte(config.GenesisCRSText))
+ g.s.PushCRS(crs)
+
+ // Round 0 height.
+ g.s.PushRoundHeight(big.NewInt(0))
+
+ // Owner.
+ g.s.SetOwner(g.config.Owner)
+
+ // Governance configuration.
+ g.s.UpdateConfiguration(config)
+
+ g.stateDB.Commit(true)
+}
+
+func (g *GovernanceContractTestSuite) newPrefundAccount() (*ecdsa.PrivateKey, common.Address) {
+ privKey, err := crypto.GenerateKey()
+ if err != nil {
+ panic(err)
+ }
+ address := crypto.PubkeyToAddress(privKey.PublicKey)
+
+ g.stateDB.AddBalance(address, new(big.Int).Mul(big.NewInt(1e18), big.NewInt(2e5)))
+ return privKey, address
+}
+
+func (g *GovernanceContractTestSuite) call(caller common.Address, input []byte, value *big.Int) ([]byte, error) {
+ context := Context{
+ CanTransfer: func(db StateDB, addr common.Address, amount *big.Int) bool {
+ return db.GetBalance(addr).Cmp(amount) >= 0
+ },
+ Transfer: func(db StateDB, sender common.Address, recipient common.Address, amount *big.Int) {
+ db.SubBalance(sender, amount)
+ db.AddBalance(recipient, amount)
+ },
+ GetRoundHeight: func(round uint64) (uint64, bool) {
+ switch round {
+ case 0:
+ return 0, true
+ case 1:
+ return 1000, true
+ case 2:
+ return 2000, true
+ }
+ return 0, false
+ },
+ Time: big.NewInt(time.Now().UnixNano() / 1000000000),
+ BlockNumber: big.NewInt(0),
+ }
+
+ evm := NewEVM(context, g.stateDB, params.TestChainConfig, Config{IsBlockProposer: true})
+ ret, _, err := evm.Call(AccountRef(caller), GovernanceContractAddress, input, 10000000, value)
+ return ret, err
+}
+
+func (g *GovernanceContractTestSuite) TestTransferOwnership() {
+ _, addr := g.newPrefundAccount()
+
+ input, err := abiObject.Pack("transferOwnership", addr)
+ g.Require().Nil(err)
+
+ // Call with non-owner.
+ _, err = g.call(addr, input, big.NewInt(0))
+ g.Require().NotNil(err)
+
+ // Call with owner.
+ _, err = g.call(g.config.Owner, input, big.NewInt(0))
+ g.Require().Nil(err)
+ g.Require().Equal(addr, g.s.Owner())
+}
+
+func (g *GovernanceContractTestSuite) TestStakeUnstakeWithoutDelegators() {
+ privKey, addr := g.newPrefundAccount()
+ pk := crypto.FromECDSAPub(&privKey.PublicKey)
+
+ // Stake.
+ amount := new(big.Int).Mul(big.NewInt(1e18), big.NewInt(5e4))
+ balanceBeforeStake := g.stateDB.GetBalance(addr)
+ input, err := abiObject.Pack("stake", pk, "Test1", "test1@dexon.org", "Taipei, Taiwan", "https://dexon.org")
+ g.Require().Nil(err)
+ _, err = g.call(addr, input, amount)
+ g.Require().Nil(err)
+
+ // Node staked but staked fund < MinStake so is still unqualified.
+ g.Require().Equal(1, int(g.s.LenNodes().Uint64()))
+ g.Require().Equal(0, len(g.s.QualifiedNodes()))
+ g.Require().Equal("Test1", g.s.Node(big.NewInt(0)).Name)
+
+ // Check balance.
+ g.Require().Equal(new(big.Int).Sub(balanceBeforeStake, amount), g.stateDB.GetBalance(addr))
+ g.Require().Equal(new(big.Int).Add(big.NewInt(1), amount), g.stateDB.GetBalance(GovernanceContractAddress))
+
+ // Staking again should fail.
+ _, err = g.call(addr, input, amount)
+ g.Require().NotNil(err)
+
+ // Unstake.
+ input, err = abiObject.Pack("unstake")
+ g.Require().Nil(err)
+ _, err = g.call(addr, input, big.NewInt(0))
+ g.Require().Nil(err)
+ g.Require().Equal(0, int(g.s.LenNodes().Uint64()))
+
+ // Stake 2 nodes, and unstake the first then the second.
+
+ // 2nd node Stake.
+ privKey2, addr2 := g.newPrefundAccount()
+ pk2 := crypto.FromECDSAPub(&privKey2.PublicKey)
+ input, err = abiObject.Pack("stake", pk2, "Test2", "test2@dexon.org", "Taipei, Taiwan", "https://dexon.org")
+ g.Require().Nil(err)
+ _, err = g.call(addr2, input, amount)
+ g.Require().Nil(err)
+ g.Require().Equal("Test2", g.s.Node(big.NewInt(0)).Name)
+ g.Require().Equal(0, int(g.s.NodesOffset(addr2).Int64()))
+
+ // 1st node Stake.
+ input, err = abiObject.Pack("stake", pk, "Test1", "test1@dexon.org", "Taipei, Taiwan", "https://dexon.org")
+ g.Require().Nil(err)
+ _, err = g.call(addr, input, amount)
+ g.Require().Nil(err)
+
+ // 2nd node Unstake.
+ input, err = abiObject.Pack("unstake")
+ g.Require().Nil(err)
+ _, err = g.call(addr2, input, big.NewInt(0))
+ g.Require().Nil(err)
+ g.Require().Equal(1, int(g.s.LenNodes().Uint64()))
+ g.Require().Equal("Test1", g.s.Node(big.NewInt(0)).Name)
+ g.Require().Equal(-1, int(g.s.NodesOffset(addr2).Int64()))
+
+ // 1st node Unstake.
+ input, err = abiObject.Pack("unstake")
+ g.Require().Nil(err)
+ _, err = g.call(addr, input, big.NewInt(0))
+ g.Require().Nil(err)
+ g.Require().Equal(0, int(g.s.LenNodes().Uint64()))
+ g.Require().Equal(-1, int(g.s.NodesOffset(addr).Int64()))
+ g.Require().Equal(-1, int(g.s.DelegatorsOffset(addr, addr).Int64()))
+
+ // Check balance.
+ g.Require().Equal(balanceBeforeStake, g.stateDB.GetBalance(addr))
+ g.Require().Equal(balanceBeforeStake, g.stateDB.GetBalance(addr2))
+ g.Require().Equal(big.NewInt(1), g.stateDB.GetBalance(GovernanceContractAddress))
+}
+
+func (g *GovernanceContractTestSuite) TestDelegateUndelegate() {
+ privKey, addr := g.newPrefundAccount()
+ pk := crypto.FromECDSAPub(&privKey.PublicKey)
+
+ // Stake.
+ input, err := abiObject.Pack("stake", pk, "Test1", "test1@dexon.org", "Taipei, Taiwan", "https://dexon.org")
+ g.Require().Nil(err)
+ ownerStaked := new(big.Int).Mul(big.NewInt(1e18), big.NewInt(5e4))
+ _, err = g.call(addr, input, ownerStaked)
+ g.Require().Nil(err)
+ g.Require().Equal(0, len(g.s.QualifiedNodes()))
+ g.Require().Equal(addr, g.s.Delegator(addr, big.NewInt(0)).Owner)
+ g.Require().Equal(ownerStaked, g.s.Node(big.NewInt(0)).Staked)
+
+ // 1st delegator delegate to 1st node.
+ _, addrDelegator := g.newPrefundAccount()
+
+ balanceBeforeDelegate := g.stateDB.GetBalance(addrDelegator)
+ amount := new(big.Int).Mul(big.NewInt(1e18), big.NewInt(3e4))
+ input, err = abiObject.Pack("delegate", addr)
+ g.Require().Nil(err)
+
+ _, err = g.call(addrDelegator, input, amount)
+ g.Require().Nil(err)
+ g.Require().Equal(new(big.Int).Sub(balanceBeforeDelegate, amount), g.stateDB.GetBalance(addrDelegator))
+ g.Require().Equal(addrDelegator, g.s.Delegator(addr, big.NewInt(1)).Owner)
+ g.Require().Equal(new(big.Int).Add(amount, ownerStaked), g.s.Node(big.NewInt(0)).Staked)
+ g.Require().Equal(1, int(g.s.DelegatorsOffset(addr, addrDelegator).Int64()))
+
+ // Same person delegate the 2nd time should fail.
+ _, err = g.call(addrDelegator, input, big.NewInt(1e18))
+ g.Require().NotNil(err)
+
+ // Not yet qualified.
+ g.Require().Equal(0, len(g.s.QualifiedNodes()))
+
+ // 2nd delegator delegate to 1st node.
+ _, addrDelegator2 := g.newPrefundAccount()
+ _, err = g.call(addrDelegator2, input, amount)
+ g.Require().Nil(err)
+ g.Require().Equal(new(big.Int).Sub(balanceBeforeDelegate, amount), g.stateDB.GetBalance(addrDelegator2))
+ g.Require().Equal(addrDelegator2, g.s.Delegator(addr, big.NewInt(2)).Owner)
+ g.Require().Equal(new(big.Int).Add(ownerStaked, new(big.Int).Mul(amount, big.NewInt(2))),
+ g.s.Node(big.NewInt(0)).Staked)
+ g.Require().Equal(2, int(g.s.DelegatorsOffset(addr, addrDelegator2).Int64()))
+
+ // Qualified.
+ g.Require().Equal(1, len(g.s.QualifiedNodes()))
+
+ // Undelegate addrDelegator.
+ balanceBeforeUnDelegate := g.stateDB.GetBalance(addrDelegator)
+ input, err = abiObject.Pack("undelegate", addr)
+ g.Require().Nil(err)
+ _, err = g.call(addrDelegator, input, big.NewInt(0))
+ g.Require().Nil(err)
+ g.Require().Equal(2, int(g.s.LenDelegators(addr).Uint64()))
+ g.Require().Equal(new(big.Int).Add(balanceBeforeUnDelegate, amount), g.stateDB.GetBalance(addrDelegator))
+ g.Require().Equal(-1, int(g.s.DelegatorsOffset(addr, addrDelegator).Int64()))
+
+ // Undelegate addrDelegator2.
+ balanceBeforeUnDelegate = g.stateDB.GetBalance(addrDelegator2)
+ input, err = abiObject.Pack("undelegate", addr)
+ g.Require().Nil(err)
+ _, err = g.call(addrDelegator2, input, big.NewInt(0))
+ g.Require().Nil(err)
+ g.Require().Equal(1, int(g.s.LenDelegators(addr).Uint64()))
+ g.Require().Equal(new(big.Int).Add(balanceBeforeUnDelegate, amount), g.stateDB.GetBalance(addrDelegator2))
+ g.Require().Equal(-1, int(g.s.DelegatorsOffset(addr, addrDelegator2).Int64()))
+
+ // Unqualified
+ g.Require().Equal(0, len(g.s.QualifiedNodes()))
+}
+
+func (g *GovernanceContractTestSuite) TestUnstakeWithDelegators() {
+ privKey, addr := g.newPrefundAccount()
+ pk := crypto.FromECDSAPub(&privKey.PublicKey)
+
+ // Stake.
+ amount := new(big.Int).Mul(big.NewInt(1e18), big.NewInt(5e4))
+ input, err := abiObject.Pack("stake", pk, "Test1", "test1@dexon.org", "Taipei, Taiwan", "https://dexon.org")
+ g.Require().Nil(err)
+ _, err = g.call(addr, input, amount)
+ g.Require().Nil(err)
+
+ // 1st delegator delegate to 1st node.
+ _, addrDelegator := g.newPrefundAccount()
+
+ balanceBeforeDelegate := g.stateDB.GetBalance(addrDelegator)
+ amount = new(big.Int).Mul(big.NewInt(1e18), big.NewInt(3e4))
+ input, err = abiObject.Pack("delegate", addr)
+ g.Require().Nil(err)
+
+ _, err = g.call(addrDelegator, input, amount)
+ g.Require().Nil(err)
+ g.Require().Equal(new(big.Int).Sub(balanceBeforeDelegate, amount), g.stateDB.GetBalance(addrDelegator))
+ g.Require().Equal(addrDelegator, g.s.Delegator(addr, big.NewInt(1)).Owner)
+ g.Require().Equal(0, len(g.s.QualifiedNodes()))
+
+ // 2st delegator delegate to 1st node.
+ _, addrDelegator2 := g.newPrefundAccount()
+
+ balanceBeforeDelegate = g.stateDB.GetBalance(addrDelegator2)
+ input, err = abiObject.Pack("delegate", addr)
+ g.Require().Nil(err)
+
+ _, err = g.call(addrDelegator2, input, amount)
+ g.Require().Nil(err)
+ g.Require().Equal(new(big.Int).Sub(balanceBeforeDelegate, amount), g.stateDB.GetBalance(addrDelegator2))
+ g.Require().Equal(addrDelegator2, g.s.Delegator(addr, big.NewInt(2)).Owner)
+
+ // Node is now qualified.
+ g.Require().Equal(1, len(g.s.QualifiedNodes()))
+
+ // Unstake.
+ input, err = abiObject.Pack("unstake")
+ g.Require().Nil(err)
+ _, err = g.call(addr, input, big.NewInt(0))
+ g.Require().Nil(err)
+ g.Require().Equal(0, int(g.s.LenDelegators(addr).Uint64()))
+ g.Require().Equal(0, int(g.s.LenNodes().Uint64()))
+
+ // Check balance.
+ g.Require().Equal(balanceBeforeDelegate, g.stateDB.GetBalance(addr))
+ g.Require().Equal(balanceBeforeDelegate, g.stateDB.GetBalance(addrDelegator))
+ g.Require().Equal(balanceBeforeDelegate, g.stateDB.GetBalance(addrDelegator2))
+ g.Require().Equal(big.NewInt(1), g.stateDB.GetBalance(GovernanceContractAddress))
+}
+
+func (g *GovernanceContractTestSuite) TestUpdateConfiguration() {
+ _, addr := g.newPrefundAccount()
+
+ input, err := abiObject.Pack("updateConfiguration",
+ new(big.Int).Mul(big.NewInt(1e18), big.NewInt(1e5)),
+ big.NewInt(1e18), big.NewInt(8000000), big.NewInt(6), big.NewInt(250), big.NewInt(2500),
+ big.NewInt(0), big.NewInt(667000), big.NewInt(4), big.NewInt(4), big.NewInt(600000), big.NewInt(900))
+ g.Require().Nil(err)
+
+ // Call with non-owner.
+ _, err = g.call(addr, input, big.NewInt(0))
+ g.Require().NotNil(err)
+
+ // Call with owner.
+ _, err = g.call(g.config.Owner, input, big.NewInt(0))
+ g.Require().Nil(err)
+}
+
+func (g *GovernanceContractTestSuite) TestSnapshotRound() {
+ _, addr := g.newPrefundAccount()
+
+ // Wrong height.
+ input, err := abiObject.Pack("snapshotRound", big.NewInt(1), big.NewInt(666))
+ g.Require().Nil(err)
+ _, err = g.call(addr, input, big.NewInt(0))
+ g.Require().NotNil(err)
+
+ // Invalid round.
+ input, err = abiObject.Pack("snapshotRound", big.NewInt(2), big.NewInt(2000))
+ g.Require().Nil(err)
+ _, err = g.call(addr, input, big.NewInt(0))
+ g.Require().NotNil(err)
+
+ // Correct.
+ input, err = abiObject.Pack("snapshotRound", big.NewInt(1), big.NewInt(1000))
+ g.Require().Nil(err)
+ _, err = g.call(addr, input, big.NewInt(0))
+ g.Require().Nil(err)
+
+ // Duplicate round.
+ input, err = abiObject.Pack("snapshotRound", big.NewInt(1), big.NewInt(1000))
+ g.Require().Nil(err)
+ _, err = g.call(addr, input, big.NewInt(0))
+ g.Require().NotNil(err)
+
+ // Invalid round.
+ input, err = abiObject.Pack("snapshotRound", big.NewInt(3), big.NewInt(3000))
+ g.Require().Nil(err)
+ _, err = g.call(addr, input, big.NewInt(0))
+ g.Require().NotNil(err)
+
+ // Correct.
+ input, err = abiObject.Pack("snapshotRound", big.NewInt(2), big.NewInt(2000))
+ g.Require().Nil(err)
+ _, err = g.call(addr, input, big.NewInt(0))
+ g.Require().Nil(err)
+}
+
+func (g *GovernanceContractTestSuite) TestConfigurationReading() {
+ _, addr := g.newPrefundAccount()
+
+ // CRS.
+ input, err := abiObject.Pack("crs", big.NewInt(0))
+ g.Require().Nil(err)
+ res, err := g.call(addr, input, big.NewInt(0))
+ g.Require().Nil(err)
+ var crs0 [32]byte
+ err = abiObject.Unpack(&crs0, "crs", res)
+ g.Require().Nil(err)
+ g.Require().Equal(crypto.Keccak256Hash([]byte(g.config.GenesisCRSText)), common.BytesToHash(crs0[:]))
+
+ // Owner.
+ input, err = abiObject.Pack("owner")
+ g.Require().Nil(err)
+ res, err = g.call(addr, input, big.NewInt(0))
+ g.Require().Nil(err)
+ var owner common.Address
+ err = abiObject.Unpack(&owner, "owner", res)
+ g.Require().Nil(err)
+ g.Require().Equal(g.config.Owner, owner)
+
+ // MinStake.
+ input, err = abiObject.Pack("minStake")
+ g.Require().Nil(err)
+ res, err = g.call(addr, input, big.NewInt(0))
+ g.Require().Nil(err)
+ var value *big.Int
+ err = abiObject.Unpack(&value, "minStake", res)
+ g.Require().Nil(err)
+ g.Require().Equal(g.config.MinStake.String(), value.String())
+
+ // BlockReward.
+ input, err = abiObject.Pack("blockReward")
+ g.Require().Nil(err)
+ res, err = g.call(addr, input, big.NewInt(0))
+ g.Require().Nil(err)
+ err = abiObject.Unpack(&value, "blockReward", res)
+ g.Require().Nil(err)
+ g.Require().Equal(g.config.BlockReward.String(), value.String())
+
+ // BlockGasLimit.
+ input, err = abiObject.Pack("blockGasLimit")
+ g.Require().Nil(err)
+ res, err = g.call(addr, input, big.NewInt(0))
+ g.Require().Nil(err)
+ err = abiObject.Unpack(&value, "blockGasLimit", res)
+ g.Require().Nil(err)
+ g.Require().Equal(g.config.BlockGasLimit, value.Uint64())
+
+ // NumChains.
+ input, err = abiObject.Pack("numChains")
+ g.Require().Nil(err)
+ res, err = g.call(addr, input, big.NewInt(0))
+ g.Require().Nil(err)
+ err = abiObject.Unpack(&value, "numChains", res)
+ g.Require().Nil(err)
+ g.Require().Equal(g.config.NumChains, uint32(value.Uint64()))
+
+ // LambdaBA.
+ input, err = abiObject.Pack("lambdaBA")
+ g.Require().Nil(err)
+ res, err = g.call(addr, input, big.NewInt(0))
+ g.Require().Nil(err)
+ err = abiObject.Unpack(&value, "lambdaBA", res)
+ g.Require().Nil(err)
+ g.Require().Equal(g.config.LambdaBA, value.Uint64())
+
+ // LambdaDKG.
+ input, err = abiObject.Pack("lambdaDKG")
+ g.Require().Nil(err)
+ res, err = g.call(addr, input, big.NewInt(0))
+ g.Require().Nil(err)
+ err = abiObject.Unpack(&value, "lambdaDKG", res)
+ g.Require().Nil(err)
+ g.Require().Equal(g.config.LambdaDKG, value.Uint64())
+
+ // K.
+ input, err = abiObject.Pack("k")
+ g.Require().Nil(err)
+ res, err = g.call(addr, input, big.NewInt(0))
+ g.Require().Nil(err)
+ err = abiObject.Unpack(&value, "k", res)
+ g.Require().Nil(err)
+ g.Require().Equal(g.config.K, uint32(value.Uint64()))
+
+ // PhiRatio.
+ input, err = abiObject.Pack("phiRatio")
+ g.Require().Nil(err)
+ res, err = g.call(addr, input, big.NewInt(0))
+ g.Require().Nil(err)
+ err = abiObject.Unpack(&value, "phiRatio", res)
+ g.Require().Nil(err)
+ g.Require().Equal(g.config.PhiRatio, float32(value.Uint64())/phiRatioMultiplier)
+
+ // NotarySetSize.
+ input, err = abiObject.Pack("notarySetSize")
+ g.Require().Nil(err)
+ res, err = g.call(addr, input, big.NewInt(0))
+ g.Require().Nil(err)
+ err = abiObject.Unpack(&value, "notarySetSize", res)
+ g.Require().Nil(err)
+ g.Require().Equal(g.config.NotarySetSize, uint32(value.Uint64()))
+
+ // DKGSetSize.
+ input, err = abiObject.Pack("dkgSetSize")
+ g.Require().Nil(err)
+ res, err = g.call(addr, input, big.NewInt(0))
+ g.Require().Nil(err)
+ err = abiObject.Unpack(&value, "dkgSetSize", res)
+ g.Require().Nil(err)
+ g.Require().Equal(g.config.DKGSetSize, uint32(value.Uint64()))
+
+ // RoundInterval.
+ input, err = abiObject.Pack("roundInterval")
+ g.Require().Nil(err)
+ res, err = g.call(addr, input, big.NewInt(0))
+ g.Require().Nil(err)
+ err = abiObject.Unpack(&value, "roundInterval", res)
+ g.Require().Nil(err)
+ g.Require().Equal(g.config.RoundInterval, value.Uint64())
+
+ // MinBlockInterval.
+ input, err = abiObject.Pack("minBlockInterval")
+ g.Require().Nil(err)
+ res, err = g.call(addr, input, big.NewInt(0))
+ g.Require().Nil(err)
+ err = abiObject.Unpack(&value, "minBlockInterval", res)
+ g.Require().Nil(err)
+ g.Require().Equal(g.config.MinBlockInterval, value.Uint64())
+}
+
+func (g *GovernanceContractTestSuite) TestMiscVariableReading() {
+ privKey, addr := g.newPrefundAccount()
+ pk := crypto.FromECDSAPub(&privKey.PublicKey)
+
+ // Stake.
+ amount := new(big.Int).Mul(big.NewInt(1e18), big.NewInt(5e4))
+ input, err := abiObject.Pack("stake", pk, "Test1", "test1@dexon.org", "Taipei, Taiwan", "https://dexon.org")
+ g.Require().Nil(err)
+ _, err = g.call(addr, input, amount)
+ g.Require().Nil(err)
+
+ // 1st delegator delegate to 1st node.
+ _, addrDelegator := g.newPrefundAccount()
+ amount = new(big.Int).Mul(big.NewInt(1e18), big.NewInt(3e4))
+ input, err = abiObject.Pack("delegate", addr)
+ g.Require().Nil(err)
+ _, err = g.call(addrDelegator, input, amount)
+ g.Require().Nil(err)
+
+ // 2st delegator delegate to 1st node.
+ _, addrDelegator2 := g.newPrefundAccount()
+ input, err = abiObject.Pack("delegate", addr)
+ g.Require().Nil(err)
+ _, err = g.call(addrDelegator2, input, amount)
+ g.Require().Nil(err)
+
+ input, err = abiObject.Pack("nodesLength")
+ g.Require().Nil(err)
+ res, err := g.call(addr, input, big.NewInt(0))
+ g.Require().Nil(err)
+ var value *big.Int
+ err = abiObject.Unpack(&value, "nodesLength", res)
+ g.Require().Nil(err)
+ g.Require().Equal(1, int(value.Uint64()))
+
+ input, err = abiObject.Pack("nodesOffset", addr)
+ g.Require().Nil(err)
+ res, err = g.call(addr, input, big.NewInt(0))
+ g.Require().Nil(err)
+ err = abiObject.Unpack(&value, "nodesOffset", res)
+ g.Require().Nil(err)
+ g.Require().Equal(0, int(value.Uint64()))
+
+ input, err = abiObject.Pack("delegatorsLength", addr)
+ g.Require().Nil(err)
+ res, err = g.call(addr, input, big.NewInt(0))
+ g.Require().Nil(err)
+ err = abiObject.Unpack(&value, "delegatorsLength", res)
+ g.Require().Nil(err)
+ g.Require().Equal(3, int(value.Uint64()))
+
+ input, err = abiObject.Pack("delegatorsOffset", addr, addrDelegator2)
+ g.Require().Nil(err)
+ res, err = g.call(addr, input, big.NewInt(0))
+ g.Require().Nil(err)
+ err = abiObject.Unpack(&value, "delegatorsOffset", res)
+ g.Require().Nil(err)
+ g.Require().Equal(2, int(value.Uint64()))
+}
+
+func TestGovernanceContract(t *testing.T) {
+ suite.Run(t, new(GovernanceContractTestSuite))
+}