diff options
author | Wei-Ning Huang <w@dexon.org> | 2018-11-19 14:36:36 +0800 |
---|---|---|
committer | Wei-Ning Huang <w@byzantine-lab.io> | 2019-06-12 17:27:18 +0800 |
commit | 78dac82d810fe4a1ad6878adbc789f909155f472 (patch) | |
tree | 13189c293ed8603a7e9d8b15571fff1737c9bc1f /core/vm/governance_test.go | |
parent | 8a0b917def2d80b112d7d8a5854aba62afc0a630 (diff) | |
download | go-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.go | 557 |
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)) +} |