aboutsummaryrefslogtreecommitdiffstats
path: root/core/vm/evm
diff options
context:
space:
mode:
Diffstat (limited to 'core/vm/evm')
-rw-r--r--core/vm/evm/oracle.go91
-rw-r--r--core/vm/evm/oracle_contract_abi.go (renamed from core/vm/evm/governance_abi.go)180
-rw-r--r--core/vm/evm/oracle_contracts.go (renamed from core/vm/evm/governance.go)1473
-rw-r--r--core/vm/evm/oracle_contracts_test.go (renamed from core/vm/evm/governance_test.go)688
4 files changed, 1622 insertions, 810 deletions
diff --git a/core/vm/evm/oracle.go b/core/vm/evm/oracle.go
new file mode 100644
index 000000000..4ee20232d
--- /dev/null
+++ b/core/vm/evm/oracle.go
@@ -0,0 +1,91 @@
+// Copyright 2019 The dexon-consensus Authors
+// This file is part of the dexon-consensus library.
+//
+// The dexon-consensus library is free software: you can redistribute it
+// and/or modify it under the terms of the GNU Lesser General Public License as
+// published by the Free Software Foundation, either version 3 of the License,
+// or (at your option) any later version.
+//
+// The dexon-consensus library is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+// General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the dexon-consensus library. If not, see
+// <http://www.gnu.org/licenses/>.
+
+package evm
+
+import (
+ "strings"
+
+ "github.com/dexon-foundation/dexon/accounts/abi"
+ "github.com/dexon-foundation/dexon/common"
+ "github.com/dexon-foundation/dexon/core/vm"
+)
+
+var GovernanceContractAddress = common.HexToAddress("63751838d6485578b23e8b051d40861ecc416794")
+var NodeInfoOracleAddress = common.HexToAddress("58a7c88ad1f32e7252bebba54def98d3e7b3df11")
+
+var GovernanceABI *OracleContractABI
+var NodeInfoOracleABI *OracleContractABI
+
+func init() {
+ GovernanceABI = NewOracleContractABI(GovernanceABIJSON)
+ NodeInfoOracleABI = NewOracleContractABI(NodeInfoOracleABIJSON)
+}
+
+// OracleContract represent special system contracts written in Go.
+type OracleContract interface {
+ Run(evm *EVM, input []byte, contract *vm.Contract) (ret []byte, err error)
+}
+
+// A map representing available system oracle contracts.
+var OracleContracts = map[common.Address]OracleContract{
+ GovernanceContractAddress: &GovernanceContract{
+ coreDKGUtils: &defaultCoreDKGUtils{},
+ },
+ NodeInfoOracleAddress: &NodeInfoOracleContract{},
+}
+
+// Run oracle contract.
+func RunOracleContract(oracle OracleContract, evm *EVM, input []byte, contract *vm.Contract) (ret []byte, err error) {
+ return oracle.Run(evm, input, contract)
+}
+
+// OracleContractABI represents ABI information for a given contract.
+type OracleContractABI struct {
+ ABI abi.ABI
+ Name2Method map[string]abi.Method
+ Sig2Method map[string]abi.Method
+ Events map[string]abi.Event
+}
+
+// NewOracleContractABI parse the ABI.
+func NewOracleContractABI(abiDefinition string) *OracleContractABI {
+ abiObject, err := abi.JSON(strings.NewReader(abiDefinition))
+ if err != nil {
+ panic(err)
+ }
+
+ sig2Method := make(map[string]abi.Method)
+ name2Method := make(map[string]abi.Method)
+
+ for _, method := range abiObject.Methods {
+ sig2Method[string(method.Id())] = method
+ name2Method[method.Name] = method
+ }
+
+ events := make(map[string]abi.Event)
+ for _, event := range abiObject.Events {
+ events[event.Name] = event
+ }
+
+ return &OracleContractABI{
+ ABI: abiObject,
+ Name2Method: name2Method,
+ Sig2Method: sig2Method,
+ Events: events,
+ }
+}
diff --git a/core/vm/evm/governance_abi.go b/core/vm/evm/oracle_contract_abi.go
index 966c4c4f3..4fb068f26 100644
--- a/core/vm/evm/governance_abi.go
+++ b/core/vm/evm/oracle_contract_abi.go
@@ -98,6 +98,25 @@ const GovernanceABIJSON = `
},
{
"constant": true,
+ "inputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "name": "DKGResetCount",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
"inputs": [],
"name": "totalSupply",
"outputs": [
@@ -673,6 +692,18 @@ const GovernanceABIJSON = `
"indexed": true,
"name": "NodeAddress",
"type": "address"
+ }
+ ],
+ "name": "NodeRemoved",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "name": "NodeAddress",
+ "type": "address"
},
{
"indexed": true,
@@ -700,6 +731,11 @@ const GovernanceABIJSON = `
"indexed": true,
"name": "DelegatorAddress",
"type": "address"
+ },
+ {
+ "indexed": false,
+ "name": "Amount",
+ "type": "uint256"
}
],
"name": "Undelegated",
@@ -714,6 +750,11 @@ const GovernanceABIJSON = `
"type": "address"
},
{
+ "indexed": true,
+ "name": "DelegatorAddress",
+ "type": "address"
+ },
+ {
"indexed": false,
"name": "Amount",
"type": "uint256"
@@ -784,6 +825,23 @@ const GovernanceABIJSON = `
"type": "event"
},
{
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "name": "Round",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "name": "BlockHeight",
+ "type": "uint256"
+ }
+ ],
+ "name": "DKGReset",
+ "type": "event"
+ },
+ {
"constant": false,
"inputs": [
{
@@ -912,24 +970,6 @@ const GovernanceABIJSON = `
"type": "uint256"
},
{
- "name": "Height",
- "type": "uint256"
- }
- ],
- "name": "snapshotRound",
- "outputs": [],
- "payable": false,
- "stateMutability": "nonpayable",
- "type": "function"
- },
- {
- "constant": false,
- "inputs": [
- {
- "name": "Round",
- "type": "uint256"
- },
- {
"name": "SignedCRS",
"type": "bytes"
}
@@ -1128,6 +1168,110 @@ const GovernanceABIJSON = `
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "NewSignedCRS",
+ "type": "bytes"
+ }
+ ],
+ "name": "resetDKG",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ }
+]
+`
+
+const NodeInfoOracleABIJSON = `
+[
+ {
+ "constant": true,
+ "inputs": [
+ {
+ "name": "Round",
+ "type": "uint256"
+ },
+ {
+ "name": "NodeAddress",
+ "type": "address"
+ },
+ {
+ "name": "Index",
+ "type": "uint256"
+ }
+ ],
+ "name": "delegators",
+ "outputs": [
+ {
+ "name": "owner",
+ "type": "address"
+ },
+ {
+ "name": "value",
+ "type": "uint256"
+ },
+ {
+ "name": "undelegated_at",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [
+ {
+ "name": "Round",
+ "type": "uint256"
+ },
+ {
+ "name": "NodeAddress",
+ "type": "address"
+ }
+ ],
+ "name": "delegatorsLength",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [
+ {
+ "name": "Round",
+ "type": "uint256"
+ },
+ {
+ "name": "NodeAddress",
+ "type": "address"
+ },
+ {
+ "name": "DelegatorAddress",
+ "type": "address"
+ }
+ ],
+ "name": "delegatorsOffset",
+ "outputs": [
+ {
+ "name": "",
+ "type": "int256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
}
]
`
diff --git a/core/vm/evm/governance.go b/core/vm/evm/oracle_contracts.go
index 18e733342..e00f65b29 100644
--- a/core/vm/evm/governance.go
+++ b/core/vm/evm/oracle_contracts.go
@@ -22,11 +22,11 @@ import (
"errors"
"math/big"
"sort"
- "strings"
"github.com/dexon-foundation/dexon/accounts/abi"
"github.com/dexon-foundation/dexon/common"
"github.com/dexon-foundation/dexon/core/types"
+ "github.com/dexon-foundation/dexon/core/vm"
"github.com/dexon-foundation/dexon/crypto"
"github.com/dexon-foundation/dexon/params"
"github.com/dexon-foundation/dexon/rlp"
@@ -35,20 +35,12 @@ import (
"github.com/dexon-foundation/dexon-consensus/core"
coreCrypto "github.com/dexon-foundation/dexon-consensus/core/crypto"
coreUtils "github.com/dexon-foundation/dexon-consensus/core/utils"
- "github.com/dexon-foundation/dexon/core/vm"
"github.com/dexon-foundation/dexon-consensus/core/crypto/ecdsa"
coreTypes "github.com/dexon-foundation/dexon-consensus/core/types"
dkgTypes "github.com/dexon-foundation/dexon-consensus/core/types/dkg"
)
-var GovernanceContractAddress = common.HexToAddress("63751838d6485578b23e8b051d40861ecc416794")
-
-var abiObject abi.ABI
-var GovernanceContractName2Method map[string]abi.Method
-var sig2Method map[string]abi.Method
-var events map[string]abi.Event
-
type Bytes32 [32]byte
type ReportType uint64
@@ -59,473 +51,6 @@ const (
ReportTypeForkBlock
)
-func init() {
- var err error
-
- // Parse governance contract ABI.
- abiObject, err = abi.JSON(strings.NewReader(GovernanceABIJSON))
- if err != nil {
- panic(err)
- }
-
- sig2Method = make(map[string]abi.Method)
- GovernanceContractName2Method = make(map[string]abi.Method)
-
- // Construct dispatch table.
- for _, method := range abiObject.Methods {
- sig2Method[string(method.Id())] = method
- GovernanceContractName2Method[method.Name] = method
- }
-
- events = make(map[string]abi.Event)
-
- // Event cache.
- for _, event := range abiObject.Events {
- events[event.Name] = event
- }
-}
-
-// RunGovernanceContract executes governance contract.
-func RunGovernanceContract(evm *EVM, input []byte, contract *vm.Contract) (ret []byte, err error) {
- if len(input) < 4 {
- return nil, nil
- }
-
- // Parse input.
- method, exists := sig2Method[string(input[:4])]
- if !exists {
- return nil, errExecutionReverted
- }
-
- // Dispatch method call.
- g := newGovernanceContract(evm, contract)
- arguments := input[4:]
-
- switch method.Name {
- case "addDKGComplaint":
- args := struct {
- Round *big.Int
- Complaint []byte
- }{}
- if err := method.Inputs.Unpack(&args, arguments); err != nil {
- return nil, errExecutionReverted
- }
- return g.addDKGComplaint(args.Round, args.Complaint)
- case "addDKGMasterPublicKey":
- args := struct {
- Round *big.Int
- PublicKey []byte
- }{}
- if err := method.Inputs.Unpack(&args, arguments); err != nil {
- return nil, errExecutionReverted
- }
- return g.addDKGMasterPublicKey(args.Round, args.PublicKey)
- case "addDKGMPKReady":
- args := struct {
- Round *big.Int
- MPKReady []byte
- }{}
- if err := method.Inputs.Unpack(&args, arguments); err != nil {
- return nil, errExecutionReverted
- }
- return g.addDKGMPKReady(args.Round, args.MPKReady)
- case "addDKGFinalize":
- args := struct {
- Round *big.Int
- Finalize []byte
- }{}
- if err := method.Inputs.Unpack(&args, arguments); err != nil {
- return nil, errExecutionReverted
- }
- return g.addDKGFinalize(args.Round, args.Finalize)
- case "delegate":
- address := common.Address{}
- if err := method.Inputs.Unpack(&address, arguments); err != nil {
- return nil, errExecutionReverted
- }
- return g.delegate(address)
- case "delegatorsLength":
- address := common.Address{}
- if err := method.Inputs.Unpack(&address, arguments); err != nil {
- return nil, errExecutionReverted
- }
- res, err := method.Outputs.Pack(g.state.LenDelegators(address))
- if err != nil {
- return nil, errExecutionReverted
- }
- return res, nil
- case "nodesLength":
- res, err := method.Outputs.Pack(g.state.LenNodes())
- if err != nil {
- return nil, errExecutionReverted
- }
- return res, nil
- case "payFine":
- address := common.Address{}
- if err := method.Inputs.Unpack(&address, arguments); err != nil {
- return nil, errExecutionReverted
- }
- return g.payFine(address)
- case "proposeCRS":
- args := struct {
- Round *big.Int
- SignedCRS []byte
- }{}
- if err := method.Inputs.Unpack(&args, arguments); err != nil {
- return nil, errExecutionReverted
- }
- return g.proposeCRS(args.Round, args.SignedCRS)
- case "report":
- args := struct {
- Type *big.Int
- Arg1 []byte
- Arg2 []byte
- }{}
- if err := method.Inputs.Unpack(&args, arguments); err != nil {
- return nil, errExecutionReverted
- }
- return g.report(args.Type, args.Arg1, args.Arg2)
- case "stake":
- args := struct {
- PublicKey []byte
- Name string
- Email string
- Location string
- Url string
- }{}
- if err := method.Inputs.Unpack(&args, arguments); err != nil {
- return nil, errExecutionReverted
- }
- return g.stake(args.PublicKey, args.Name, args.Email, args.Location, args.Url)
- case "snapshotRound":
- args := struct {
- Round *big.Int
- Height *big.Int
- }{}
- if err := method.Inputs.Unpack(&args, arguments); err != nil {
- return nil, errExecutionReverted
- }
- return g.snapshotRound(args.Round, args.Height)
- case "transferOwnership":
- var newOwner common.Address
- if err := method.Inputs.Unpack(&newOwner, arguments); err != nil {
- return nil, errExecutionReverted
- }
- return g.transferOwnership(newOwner)
- case "undelegate":
- address := common.Address{}
- if err := method.Inputs.Unpack(&address, arguments); err != nil {
- return nil, errExecutionReverted
- }
- return g.undelegate(address)
- case "unstake":
- return g.unstake()
- case "updateConfiguration":
- var cfg rawConfigStruct
- if err := method.Inputs.Unpack(&cfg, arguments); err != nil {
- return nil, errExecutionReverted
- }
- return g.updateConfiguration(&cfg)
- case "withdraw":
- address := common.Address{}
- if err := method.Inputs.Unpack(&address, arguments); err != nil {
- return nil, errExecutionReverted
- }
- return g.withdraw(address)
-
- // --------------------------------
- // Solidity auto generated methods.
- // --------------------------------
-
- case "blockGasLimit":
- res, err := method.Outputs.Pack(g.state.BlockGasLimit())
- if err != nil {
- return nil, errExecutionReverted
- }
- return res, nil
- case "crs":
- round := new(big.Int)
- if err := method.Inputs.Unpack(&round, arguments); err != nil {
- return nil, errExecutionReverted
- }
- res, err := method.Outputs.Pack(g.state.CRS(round))
- if err != nil {
- return nil, errExecutionReverted
- }
- return res, nil
- case "delegators":
- nodeAddr, index := common.Address{}, new(big.Int)
- args := []interface{}{&nodeAddr, &index}
- if err := method.Inputs.Unpack(&args, arguments); err != nil {
- return nil, errExecutionReverted
- }
- delegator := g.state.Delegator(nodeAddr, index)
- res, err := method.Outputs.Pack(delegator.Owner, delegator.Value, delegator.UndelegatedAt)
- if err != nil {
- return nil, errExecutionReverted
- }
- return res, nil
- case "delegatorsOffset":
- nodeAddr, delegatorAddr := common.Address{}, common.Address{}
- args := []interface{}{&nodeAddr, &delegatorAddr}
- if err := method.Inputs.Unpack(&args, arguments); err != nil {
- return nil, errExecutionReverted
- }
- res, err := method.Outputs.Pack(g.state.DelegatorsOffset(nodeAddr, delegatorAddr))
- if err != nil {
- return nil, errExecutionReverted
- }
- return res, nil
- case "dkgComplaints":
- round, index := new(big.Int), new(big.Int)
- args := []interface{}{&round, &index}
- if err := method.Inputs.Unpack(&args, arguments); err != nil {
- return nil, errExecutionReverted
- }
- complaints := g.state.DKGComplaints(round)
- if int(index.Uint64()) >= len(complaints) {
- return nil, errExecutionReverted
- }
- complaint := complaints[index.Uint64()]
- res, err := method.Outputs.Pack(complaint)
- if err != nil {
- return nil, errExecutionReverted
- }
- return res, nil
- case "dkgReadys":
- round, addr := new(big.Int), common.Address{}
- args := []interface{}{&round, &addr}
- if err := method.Inputs.Unpack(&args, arguments); err != nil {
- return nil, errExecutionReverted
- }
- ready := g.state.DKGMPKReady(round, addr)
- res, err := method.Outputs.Pack(ready)
- if err != nil {
- return nil, errExecutionReverted
- }
- return res, nil
- case "dkgReadysCount":
- round := new(big.Int)
- if err := method.Inputs.Unpack(&round, arguments); err != nil {
- return nil, errExecutionReverted
- }
- count := g.state.DKGMPKReadysCount(round)
- res, err := method.Outputs.Pack(count)
- if err != nil {
- return nil, errExecutionReverted
- }
- return res, nil
-
- case "dkgFinalizeds":
- round, addr := new(big.Int), common.Address{}
- args := []interface{}{&round, &addr}
- if err := method.Inputs.Unpack(&args, arguments); err != nil {
- return nil, errExecutionReverted
- }
- finalized := g.state.DKGFinalized(round, addr)
- res, err := method.Outputs.Pack(finalized)
- if err != nil {
- return nil, errExecutionReverted
- }
- return res, nil
- case "dkgFinalizedsCount":
- round := new(big.Int)
- if err := method.Inputs.Unpack(&round, arguments); err != nil {
- return nil, errExecutionReverted
- }
- count := g.state.DKGFinalizedsCount(round)
- res, err := method.Outputs.Pack(count)
- if err != nil {
- return nil, errExecutionReverted
- }
- return res, nil
- case "dkgMasterPublicKeys":
- round, index := new(big.Int), new(big.Int)
- args := []interface{}{&round, &index}
- if err := method.Inputs.Unpack(&args, arguments); err != nil {
- return nil, errExecutionReverted
- }
- mpks := g.state.DKGMasterPublicKeys(round)
- if int(index.Uint64()) >= len(mpks) {
- return nil, errExecutionReverted
- }
- mpk := mpks[index.Uint64()]
- res, err := method.Outputs.Pack(mpk)
- if err != nil {
- return nil, errExecutionReverted
- }
- return res, nil
- case "dkgSetSize":
- res, err := method.Outputs.Pack(g.state.DKGSetSize())
- if err != nil {
- return nil, errExecutionReverted
- }
- return res, nil
- case "finedRecords":
- record := Bytes32{}
- if err := method.Inputs.Unpack(&record, arguments); err != nil {
- return nil, errExecutionReverted
- }
- value := g.state.FineRecords(record)
- res, err := method.Outputs.Pack(value)
- if err != nil {
- return nil, errExecutionReverted
- }
- return res, nil
- case "fineValues":
- index := new(big.Int)
- if err := method.Inputs.Unpack(&index, arguments); err != nil {
- return nil, errExecutionReverted
- }
- value := g.state.FineValue(index)
- res, err := method.Outputs.Pack(value)
- if err != nil {
- return nil, errExecutionReverted
- }
- return res, nil
- case "k":
- res, err := method.Outputs.Pack(g.state.K())
- if err != nil {
- return nil, errExecutionReverted
- }
- return res, nil
- case "lambdaBA":
- res, err := method.Outputs.Pack(g.state.LambdaBA())
- if err != nil {
- return nil, errExecutionReverted
- }
- return res, nil
- case "lambdaDKG":
- res, err := method.Outputs.Pack(g.state.LambdaDKG())
- if err != nil {
- return nil, errExecutionReverted
- }
- return res, nil
- case "lastHalvedAmount":
- res, err := method.Outputs.Pack(g.state.LastHalvedAmount())
- if err != nil {
- return nil, errExecutionReverted
- }
- return res, nil
- case "lockupPeriod":
- res, err := method.Outputs.Pack(g.state.LockupPeriod())
- if err != nil {
- return nil, errExecutionReverted
- }
- return res, nil
- case "minBlockInterval":
- res, err := method.Outputs.Pack(g.state.MinBlockInterval())
- if err != nil {
- return nil, errExecutionReverted
- }
- return res, nil
- case "miningVelocity":
- res, err := method.Outputs.Pack(g.state.MiningVelocity())
- if err != nil {
- return nil, errExecutionReverted
- }
- return res, nil
- case "minStake":
- res, err := method.Outputs.Pack(g.state.MinStake())
- if err != nil {
- return nil, errExecutionReverted
- }
- return res, nil
- case "nextHalvingSupply":
- res, err := method.Outputs.Pack(g.state.NextHalvingSupply())
- if err != nil {
- return nil, errExecutionReverted
- }
- return res, nil
- case "numChains":
- res, err := method.Outputs.Pack(g.state.NumChains())
- if err != nil {
- return nil, errExecutionReverted
- }
- return res, nil
- case "nodes":
- index := new(big.Int)
- if err := method.Inputs.Unpack(&index, arguments); err != nil {
- return nil, errExecutionReverted
- }
- info := g.state.Node(index)
- res, err := method.Outputs.Pack(
- info.Owner, info.PublicKey, info.Staked, info.Fined,
- info.Name, info.Email, info.Location, info.Url)
- if err != nil {
- return nil, errExecutionReverted
- }
- return res, nil
- case "nodesOffsetByAddress":
- address := common.Address{}
- if err := method.Inputs.Unpack(&address, arguments); err != nil {
- return nil, errExecutionReverted
- }
- res, err := method.Outputs.Pack(g.state.NodesOffsetByAddress(address))
- if err != nil {
- return nil, errExecutionReverted
- }
- return res, nil
- case "nodesOffsetByID":
- var id Bytes32
- if err := method.Inputs.Unpack(&id, arguments); err != nil {
- return nil, errExecutionReverted
- }
- res, err := method.Outputs.Pack(g.state.NodesOffsetByID(id))
- if err != nil {
- return nil, errExecutionReverted
- }
- return res, nil
- case "notarySetSize":
- res, err := method.Outputs.Pack(g.state.NotarySetSize())
- if err != nil {
- return nil, errExecutionReverted
- }
- return res, nil
- case "owner":
- res, err := method.Outputs.Pack(g.state.Owner())
- if err != nil {
- return nil, errExecutionReverted
- }
- return res, nil
- case "phiRatio":
- res, err := method.Outputs.Pack(g.state.PhiRatio())
- if err != nil {
- return nil, errExecutionReverted
- }
- return res, nil
- case "roundHeight":
- round := new(big.Int)
- if err := method.Inputs.Unpack(&round, arguments); err != nil {
- return nil, errExecutionReverted
- }
- res, err := method.Outputs.Pack(g.state.RoundHeight(round))
- if err != nil {
- return nil, errExecutionReverted
- }
- return res, nil
- case "roundInterval":
- res, err := method.Outputs.Pack(g.state.RoundInterval())
- if err != nil {
- return nil, errExecutionReverted
- }
- return res, nil
- case "totalStaked":
- res, err := method.Outputs.Pack(g.state.TotalStaked())
- if err != nil {
- return nil, errExecutionReverted
- }
- return res, nil
- case "totalSupply":
- res, err := method.Outputs.Pack(g.state.TotalSupply())
- if err != nil {
- return nil, errExecutionReverted
- }
- return res, nil
- }
- return nil, errExecutionReverted
-}
-
// Storage position enums.
const (
roundHeightLoc = iota
@@ -561,6 +86,7 @@ const (
minBlockIntervalLoc
fineValuesLoc
finedRecordsLoc
+ dkgResetCountLoc
)
func publicKeyToNodeID(pkBytes []byte) (Bytes32, error) {
@@ -681,6 +207,29 @@ func (s *GovernanceStateHelper) writeBytes(loc *big.Int, data []byte) {
}
}
+func (s *GovernanceStateHelper) eraseBytes(loc *big.Int) {
+ // Length of the dynamic array (bytes).
+ rawLength := s.getStateBigInt(loc)
+ lengthByte := new(big.Int).Mod(rawLength, big.NewInt(256))
+
+ // Bytes length <= 31, lengthByte % 2 == 0
+ // return the high 31 bytes.
+ if new(big.Int).Mod(lengthByte, big.NewInt(2)).Cmp(big.NewInt(0)) == 0 {
+ s.setStateBigInt(loc, big.NewInt(0))
+ return
+ }
+
+ // Actual length = (rawLength - 1) / 2
+ length := new(big.Int).Div(new(big.Int).Sub(
+ rawLength, big.NewInt(1)), big.NewInt(2)).Uint64()
+
+ // Fill 0.
+ s.writeBytes(loc, make([]byte, length))
+
+ // Clear slot.
+ s.setStateBigInt(loc, big.NewInt(0))
+}
+
func (s *GovernanceStateHelper) read2DByteArray(pos, index *big.Int) [][]byte {
baseLoc := s.getSlotLoc(pos)
loc := new(big.Int).Add(baseLoc, index)
@@ -696,6 +245,7 @@ func (s *GovernanceStateHelper) read2DByteArray(pos, index *big.Int) [][]byte {
return data
}
+
func (s *GovernanceStateHelper) appendTo2DByteArray(pos, index *big.Int, data []byte) {
// Find the loc of the last element.
baseLoc := s.getSlotLoc(pos)
@@ -711,10 +261,21 @@ func (s *GovernanceStateHelper) appendTo2DByteArray(pos, index *big.Int, data []
s.writeBytes(elementLoc, data)
}
-// uint256[] public roundHeight;
-func (s *GovernanceStateHelper) LenRoundHeight() *big.Int {
- return s.getStateBigInt(big.NewInt(roundHeightLoc))
+func (s *GovernanceStateHelper) erase2DByteArray(pos, index *big.Int) {
+ baseLoc := s.getSlotLoc(pos)
+ loc := new(big.Int).Add(baseLoc, index)
+
+ arrayLength := s.getStateBigInt(loc)
+ dataLoc := s.getSlotLoc(loc)
+
+ for i := int64(0); i < int64(arrayLength.Uint64()); i++ {
+ elementLoc := new(big.Int).Add(dataLoc, big.NewInt(i))
+ s.eraseBytes(elementLoc)
+ }
+ s.setStateBigInt(loc, big.NewInt(0))
}
+
+// uint256[] public roundHeight;
func (s *GovernanceStateHelper) RoundHeight(round *big.Int) *big.Int {
baseLoc := s.getSlotLoc(big.NewInt(roundHeightLoc))
loc := new(big.Int).Add(baseLoc, round)
@@ -1049,6 +610,16 @@ func (s *GovernanceStateHelper) PushCRS(crs common.Hash) {
s.setState(common.BigToHash(loc), crs)
}
+func (s *GovernanceStateHelper) PopCRS() {
+ // decrease length by 1.
+ length := s.getStateBigInt(big.NewInt(crsLoc))
+ s.setStateBigInt(big.NewInt(crsLoc), new(big.Int).Sub(length, big.NewInt(1)))
+
+ baseLoc := s.getSlotLoc(big.NewInt(crsLoc))
+ loc := new(big.Int).Add(baseLoc, length)
+
+ s.setState(common.BigToHash(loc), common.Hash{})
+}
func (s *GovernanceStateHelper) Round() *big.Int {
return new(big.Int).Sub(s.getStateBigInt(big.NewInt(crsLoc)), big.NewInt(1))
}
@@ -1093,6 +664,9 @@ func (s *GovernanceStateHelper) GetDKGMasterPublicKeyByProposerID(
}
return nil, errors.New("not found")
}
+func (s *GovernanceStateHelper) ClearDKGMasterPublicKeys(round *big.Int) {
+ s.erase2DByteArray(big.NewInt(dkgMasterPublicKeysLoc), round)
+}
// bytes[][] public dkgComplaints;
func (s *GovernanceStateHelper) DKGComplaints(round *big.Int) [][]byte {
@@ -1101,6 +675,9 @@ func (s *GovernanceStateHelper) DKGComplaints(round *big.Int) [][]byte {
func (s *GovernanceStateHelper) PushDKGComplaint(round *big.Int, complaint []byte) {
s.appendTo2DByteArray(big.NewInt(dkgComplaintsLoc), round, complaint)
}
+func (s *GovernanceStateHelper) ClearDKGComplaints(round *big.Int) {
+ s.erase2DByteArray(big.NewInt(dkgComplaintsLoc), round)
+}
// mapping(address => bool)[] public dkgReady;
func (s *GovernanceStateHelper) DKGMPKReady(round *big.Int, addr common.Address) bool {
@@ -1117,6 +694,16 @@ func (s *GovernanceStateHelper) PutDKGMPKReady(round *big.Int, addr common.Addre
}
s.setStateBigInt(mapLoc, res)
}
+func (s *GovernanceStateHelper) ClearDKGMPKReady(round *big.Int, dkgSet map[coreTypes.NodeID]struct{}) {
+ for id := range dkgSet {
+ offset := s.NodesOffsetByID(Bytes32(id.Hash))
+ if offset.Cmp(big.NewInt(0)) < 0 {
+ panic(errors.New("DKG node does not exist"))
+ }
+ node := s.Node(offset)
+ s.PutDKGMPKReady(round, node.Owner, false)
+ }
+}
// uint256[] public dkgReadysCount;
func (s *GovernanceStateHelper) DKGMPKReadysCount(round *big.Int) *big.Int {
@@ -1128,6 +715,10 @@ func (s *GovernanceStateHelper) IncDKGMPKReadysCount(round *big.Int) {
count := s.getStateBigInt(loc)
s.setStateBigInt(loc, new(big.Int).Add(count, big.NewInt(1)))
}
+func (s *GovernanceStateHelper) ResetDKGMPKReadysCount(round *big.Int) {
+ loc := new(big.Int).Add(s.getSlotLoc(big.NewInt(dkgReadysCountLoc)), round)
+ s.setStateBigInt(loc, big.NewInt(0))
+}
// mapping(address => bool)[] public dkgFinalized;
func (s *GovernanceStateHelper) DKGFinalized(round *big.Int, addr common.Address) bool {
@@ -1144,6 +735,16 @@ func (s *GovernanceStateHelper) PutDKGFinalized(round *big.Int, addr common.Addr
}
s.setStateBigInt(mapLoc, res)
}
+func (s *GovernanceStateHelper) ClearDKGFinalized(round *big.Int, dkgSet map[coreTypes.NodeID]struct{}) {
+ for id := range dkgSet {
+ offset := s.NodesOffsetByID(Bytes32(id.Hash))
+ if offset.Cmp(big.NewInt(0)) < 0 {
+ panic(errors.New("DKG node does not exist"))
+ }
+ node := s.Node(offset)
+ s.PutDKGFinalized(round, node.Owner, false)
+ }
+}
// uint256[] public dkgFinalizedsCount;
func (s *GovernanceStateHelper) DKGFinalizedsCount(round *big.Int) *big.Int {
@@ -1155,6 +756,10 @@ func (s *GovernanceStateHelper) IncDKGFinalizedsCount(round *big.Int) {
count := s.getStateBigInt(loc)
s.setStateBigInt(loc, new(big.Int).Add(count, big.NewInt(1)))
}
+func (s *GovernanceStateHelper) ResetDKGFinalizedsCount(round *big.Int) {
+ loc := new(big.Int).Add(s.getSlotLoc(big.NewInt(dkgFinalizedsCountLoc)), round)
+ s.setStateBigInt(loc, big.NewInt(0))
+}
// address public owner;
func (s *GovernanceStateHelper) Owner() common.Address {
@@ -1283,7 +888,7 @@ func (s *GovernanceStateHelper) SetFineValues(values []*big.Int) {
}
}
-// uint256[] public fineRdecords;
+// mapping(bytes32 => bool) public fineRdecords;
func (s *GovernanceStateHelper) FineRecords(recordHash Bytes32) bool {
loc := s.getMapLoc(big.NewInt(finedRecordsLoc), recordHash[:])
return s.getStateBigInt(loc).Cmp(big.NewInt(0)) > 0
@@ -1297,6 +902,17 @@ func (s *GovernanceStateHelper) SetFineRecords(recordHash Bytes32, status bool)
s.setStateBigInt(loc, big.NewInt(value))
}
+// uint256[] public DKGResetCount;
+func (s *GovernanceStateHelper) DKGResetCount(round *big.Int) *big.Int {
+ arrayBaseLoc := s.getSlotLoc(big.NewInt(dkgResetCountLoc))
+ return s.getStateBigInt(new(big.Int).Add(arrayBaseLoc, round))
+}
+func (s *GovernanceStateHelper) IncDKGResetCount(round *big.Int) {
+ loc := new(big.Int).Add(s.getSlotLoc(big.NewInt(dkgResetCountLoc)), round)
+ count := s.getStateBigInt(loc)
+ s.setStateBigInt(loc, new(big.Int).Add(count, big.NewInt(1)))
+}
+
// Stake is a helper function for creating genesis state.
func (s *GovernanceStateHelper) Stake(
addr common.Address, publicKey []byte, staked *big.Int,
@@ -1416,7 +1032,7 @@ func (s *GovernanceStateHelper) UpdateConfigurationRaw(cfg *rawConfigStruct) {
func (s *GovernanceStateHelper) emitConfigurationChangedEvent() {
s.StateDB.AddLog(&types.Log{
Address: GovernanceContractAddress,
- Topics: []common.Hash{events["ConfigurationChanged"].Id()},
+ Topics: []common.Hash{GovernanceABI.Events["ConfigurationChanged"].Id()},
Data: []byte{},
})
}
@@ -1425,7 +1041,7 @@ func (s *GovernanceStateHelper) emitConfigurationChangedEvent() {
func (s *GovernanceStateHelper) emitCRSProposed(round *big.Int, crs common.Hash) {
s.StateDB.AddLog(&types.Log{
Address: GovernanceContractAddress,
- Topics: []common.Hash{events["CRSProposed"].Id(), common.BigToHash(round)},
+ Topics: []common.Hash{GovernanceABI.Events["CRSProposed"].Id(), common.BigToHash(round)},
Data: crs.Bytes(),
})
}
@@ -1434,7 +1050,7 @@ func (s *GovernanceStateHelper) emitCRSProposed(round *big.Int, crs common.Hash)
func (s *GovernanceStateHelper) emitStaked(nodeAddr common.Address) {
s.StateDB.AddLog(&types.Log{
Address: GovernanceContractAddress,
- Topics: []common.Hash{events["Staked"].Id(), nodeAddr.Hash()},
+ Topics: []common.Hash{GovernanceABI.Events["Staked"].Id(), nodeAddr.Hash()},
Data: []byte{},
})
}
@@ -1443,7 +1059,16 @@ func (s *GovernanceStateHelper) emitStaked(nodeAddr common.Address) {
func (s *GovernanceStateHelper) emitUnstaked(nodeAddr common.Address) {
s.StateDB.AddLog(&types.Log{
Address: GovernanceContractAddress,
- Topics: []common.Hash{events["Unstaked"].Id(), nodeAddr.Hash()},
+ Topics: []common.Hash{GovernanceABI.Events["Unstaked"].Id(), nodeAddr.Hash()},
+ Data: []byte{},
+ })
+}
+
+// event NodeRemoved(address indexed NodeAddress);
+func (s *GovernanceStateHelper) emitNodeRemoved(nodeAddr common.Address) {
+ s.StateDB.AddLog(&types.Log{
+ Address: GovernanceContractAddress,
+ Topics: []common.Hash{GovernanceABI.Events["NodeRemoved"].Id(), nodeAddr.Hash()},
Data: []byte{},
})
}
@@ -1452,25 +1077,25 @@ func (s *GovernanceStateHelper) emitUnstaked(nodeAddr common.Address) {
func (s *GovernanceStateHelper) emitDelegated(nodeAddr, delegatorAddr common.Address, amount *big.Int) {
s.StateDB.AddLog(&types.Log{
Address: GovernanceContractAddress,
- Topics: []common.Hash{events["Delegated"].Id(), nodeAddr.Hash(), delegatorAddr.Hash()},
+ Topics: []common.Hash{GovernanceABI.Events["Delegated"].Id(), nodeAddr.Hash(), delegatorAddr.Hash()},
Data: common.BigToHash(amount).Bytes(),
})
}
-// event Undelegated(address indexed NodeAddress, address indexed DelegatorAddress);
-func (s *GovernanceStateHelper) emitUndelegated(nodeAddr, delegatorAddr common.Address) {
+// event Undelegated(address indexed NodeAddress, address indexed DelegatorAddress, uint256 Amount);
+func (s *GovernanceStateHelper) emitUndelegated(nodeAddr, delegatorAddr common.Address, amount *big.Int) {
s.StateDB.AddLog(&types.Log{
Address: GovernanceContractAddress,
- Topics: []common.Hash{events["Undelegated"].Id(), nodeAddr.Hash(), delegatorAddr.Hash()},
- Data: []byte{},
+ Topics: []common.Hash{GovernanceABI.Events["Undelegated"].Id(), nodeAddr.Hash(), delegatorAddr.Hash()},
+ Data: common.BigToHash(amount).Bytes(),
})
}
-// event Withdrawn(address indexed NodeAddress, uint256 Amount);
-func (s *GovernanceStateHelper) emitWithdrawn(nodeAddr common.Address, amount *big.Int) {
+// event Withdrawn(address indexed NodeAddress, address indexed DelegatorAddress, uint256 Amount);
+func (s *GovernanceStateHelper) emitWithdrawn(nodeAddr common.Address, delegatorAddr common.Address, amount *big.Int) {
s.StateDB.AddLog(&types.Log{
Address: GovernanceContractAddress,
- Topics: []common.Hash{events["Withdrawn"].Id(), nodeAddr.Hash()},
+ Topics: []common.Hash{GovernanceABI.Events["Withdrawn"].Id(), nodeAddr.Hash(), delegatorAddr.Hash()},
Data: common.BigToHash(amount).Bytes(),
})
}
@@ -1502,7 +1127,7 @@ func (s *GovernanceStateHelper) emitForkReported(nodeAddr common.Address, report
}
s.StateDB.AddLog(&types.Log{
Address: GovernanceContractAddress,
- Topics: []common.Hash{events["ForkReported"].Id(), nodeAddr.Hash()},
+ Topics: []common.Hash{GovernanceABI.Events["ForkReported"].Id(), nodeAddr.Hash()},
Data: data,
})
}
@@ -1511,7 +1136,7 @@ func (s *GovernanceStateHelper) emitForkReported(nodeAddr common.Address, report
func (s *GovernanceStateHelper) emitFined(nodeAddr common.Address, amount *big.Int) {
s.StateDB.AddLog(&types.Log{
Address: GovernanceContractAddress,
- Topics: []common.Hash{events["Fined"].Id(), nodeAddr.Hash()},
+ Topics: []common.Hash{GovernanceABI.Events["Fined"].Id(), nodeAddr.Hash()},
Data: common.BigToHash(amount).Bytes(),
})
}
@@ -1520,24 +1145,79 @@ func (s *GovernanceStateHelper) emitFined(nodeAddr common.Address, amount *big.I
func (s *GovernanceStateHelper) emitFinePaid(nodeAddr common.Address, amount *big.Int) {
s.StateDB.AddLog(&types.Log{
Address: GovernanceContractAddress,
- Topics: []common.Hash{events["FinePaid"].Id(), nodeAddr.Hash()},
+ Topics: []common.Hash{GovernanceABI.Events["FinePaid"].Id(), nodeAddr.Hash()},
Data: common.BigToHash(amount).Bytes(),
})
}
+// event DKGReset(uint256 indexed Round, uint256 BlockHeight);
+func (s *GovernanceStateHelper) emitDKGReset(round *big.Int, blockHeight *big.Int) {
+ s.StateDB.AddLog(&types.Log{
+ Address: GovernanceContractAddress,
+ Topics: []common.Hash{GovernanceABI.Events["DKGReset"].Id(), common.BigToHash(round)},
+ Data: common.BigToHash(blockHeight).Bytes(),
+ })
+}
+
+func getConfigState(evm *EVM, round *big.Int) (*GovernanceStateHelper, error) {
+ configRound := big.NewInt(0)
+ if round.Uint64() >= core.ConfigRoundShift {
+ configRound = new(big.Int).Sub(round, big.NewInt(int64(core.ConfigRoundShift-1)))
+ }
+
+ gs := &GovernanceStateHelper{evm.StateDB}
+ height := gs.RoundHeight(configRound).Uint64()
+ if round.Uint64() >= core.ConfigRoundShift {
+ if height == 0 {
+ return nil, errExecutionReverted
+ }
+ height--
+ }
+ statedb, err := evm.StateAtNumber(height)
+ return &GovernanceStateHelper{statedb}, err
+}
+
+type coreDKGUtils interface {
+ SetState(GovernanceStateHelper)
+ NewGroupPublicKey(*big.Int, int) (tsigVerifierIntf, error)
+}
+type tsigVerifierIntf interface {
+ VerifySignature(coreCommon.Hash, coreCrypto.Signature) bool
+}
+
// GovernanceContract represents the governance contract of DEXCON.
type GovernanceContract struct {
- evm *EVM
- state GovernanceStateHelper
- contract *vm.Contract
+ evm *EVM
+ state GovernanceStateHelper
+ contract *vm.Contract
+ coreDKGUtils coreDKGUtils
+}
+
+// defaultCoreDKGUtils implements coreDKGUtils.
+type defaultCoreDKGUtils struct {
+ state GovernanceStateHelper
}
-func newGovernanceContract(evm *EVM, contract *vm.Contract) *GovernanceContract {
- return &GovernanceContract{
- evm: evm,
- state: GovernanceStateHelper{evm.StateDB},
- contract: contract,
+func (c *defaultCoreDKGUtils) SetState(state GovernanceStateHelper) {
+ c.state = state
+}
+
+func (c *defaultCoreDKGUtils) NewGroupPublicKey(round *big.Int,
+ threshold int) (tsigVerifierIntf, error) {
+ // Prepare DKGMasterPublicKeys.
+ mpks := c.state.UniqueDKGMasterPublicKeys(round)
+
+ // Prepare DKGComplaints.
+ var complaints []*dkgTypes.Complaint
+ for _, comp := range c.state.DKGComplaints(round) {
+ x := new(dkgTypes.Complaint)
+ if err := rlp.DecodeBytes(comp, x); err != nil {
+ panic(err)
+ }
+ complaints = append(complaints, x)
}
+
+ return core.NewDKGGroupPublicKey(round.Uint64(), mpks, complaints, threshold)
}
func (g *GovernanceContract) Address() common.Address {
@@ -1565,21 +1245,21 @@ func (g *GovernanceContract) penalize() ([]byte, error) {
return nil, errExecutionReverted
}
-func (g *GovernanceContract) inDKGSet(round *big.Int, nodeID coreTypes.NodeID) bool {
- target := coreTypes.NewDKGSetTarget(coreCommon.Hash(g.state.CurrentCRS()))
- ns := coreTypes.NewNodeSet()
-
- configRound := big.NewInt(0) // If round < core.ConfigRoundShift, use 0.
- if round.Uint64() >= core.ConfigRoundShift {
- configRound = new(big.Int).Sub(round, big.NewInt(int64(core.ConfigRoundShift)))
+func (g *GovernanceContract) configDKGSetSize(round *big.Int) *big.Int {
+ s, err := getConfigState(g.evm, round)
+ if err != nil {
+ panic(err)
}
+ return s.DKGSetSize()
+}
+func (g *GovernanceContract) getDKGSet(round *big.Int) map[coreTypes.NodeID]struct{} {
+ target := coreTypes.NewDKGSetTarget(coreCommon.Hash(g.state.CRS(round)))
+ ns := coreTypes.NewNodeSet()
- statedb, err := g.evm.StateAtNumber(g.state.RoundHeight(configRound).Uint64())
+ state, err := getConfigState(g.evm, round)
if err != nil {
panic(err)
}
-
- state := GovernanceStateHelper{statedb}
for _, x := range state.QualifiedNodes() {
mpk, err := ecdsa.NewPublicKeyFromByteSlice(x.PublicKey)
if err != nil {
@@ -1587,8 +1267,11 @@ func (g *GovernanceContract) inDKGSet(round *big.Int, nodeID coreTypes.NodeID) b
}
ns.Add(coreTypes.NewNodeID(mpk))
}
+ return ns.GetSubSet(int(g.configDKGSetSize(round).Uint64()), target)
+}
- dkgSet := ns.GetSubSet(int(g.state.DKGSetSize().Uint64()), target)
+func (g *GovernanceContract) inDKGSet(round *big.Int, nodeID coreTypes.NodeID) bool {
+ dkgSet := g.getDKGSet(round)
_, ok := dkgSet[nodeID]
return ok
}
@@ -1898,7 +1581,7 @@ func (g *GovernanceContract) undelegateHelper(nodeAddr, caller common.Address) (
// Subtract to network total staked.
g.state.DecTotalStaked(delegator.Value)
- g.state.emitUndelegated(nodeAddr, caller)
+ g.state.emitUndelegated(nodeAddr, caller, delegator.Value)
return g.useGas(100000)
}
@@ -1949,7 +1632,7 @@ func (g *GovernanceContract) withdraw(nodeAddr common.Address) ([]byte, error) {
return nil, errExecutionReverted
}
- g.state.emitWithdrawn(nodeAddr, delegator.Value)
+ g.state.emitWithdrawn(nodeAddr, delegator.Owner, delegator.Value)
// We are the last delegator to withdraw the fund, remove the node info.
if g.state.LenDelegators(nodeAddr).Cmp(big.NewInt(0)) == 0 {
@@ -1966,6 +1649,7 @@ func (g *GovernanceContract) withdraw(nodeAddr common.Address) ([]byte, error) {
}
g.state.DeleteNodesOffsetByAddress(nodeAddr)
g.state.PopLastNode()
+ g.state.emitNodeRemoved(nodeAddr)
}
return g.useGas(100000)
@@ -2036,23 +1720,10 @@ func (g *GovernanceContract) proposeCRS(nextRound *big.Int, signedCRS []byte) ([
prevCRS := g.state.CRS(round)
- // Prepare DKGMasterPublicKeys.
- dkgMasterPKs := g.state.UniqueDKGMasterPublicKeys(round)
-
- // Prepare DKGComplaints.
- var dkgComplaints []*dkgTypes.Complaint
- for _, comp := range g.state.DKGComplaints(round) {
- x := new(dkgTypes.Complaint)
- if err := rlp.DecodeBytes(comp, x); err != nil {
- panic(err)
- }
- dkgComplaints = append(dkgComplaints, x)
- }
-
threshold := int(g.state.DKGSetSize().Uint64()/3 + 1)
- dkgGPK, err := core.NewDKGGroupPublicKey(
- round.Uint64(), dkgMasterPKs, dkgComplaints, threshold)
+ dkgGPK, err := g.coreDKGUtils.NewGroupPublicKey(
+ round, threshold)
if err != nil {
return nil, errExecutionReverted
}
@@ -2163,6 +1834,556 @@ func (g *GovernanceContract) report(reportType *big.Int, arg1, arg2 []byte) ([]b
return nil, nil
}
+func (g *GovernanceContract) resetDKG(newSignedCRS []byte) ([]byte, error) {
+ // Check if current block over 80% of current round.
+ round := g.state.Round()
+ resetCount := g.state.DKGResetCount(round)
+ // Just restart DEXON if failed at round 0.
+ if round.Cmp(big.NewInt(0)) == 0 {
+ return nil, errExecutionReverted
+ }
+
+ // target = 80 + 100 * DKGResetCount
+ target := new(big.Int).Add(
+ big.NewInt(80),
+ new(big.Int).Mul(big.NewInt(100), resetCount))
+
+ // Round() is increased if CRS is signed. But we want to extend round r-1 now.
+ curRound := new(big.Int).Sub(round, big.NewInt(1))
+ roundHeight := g.state.RoundHeight(curRound)
+ gs, err := getConfigState(g.evm, curRound)
+ if err != nil {
+ return nil, err
+ }
+ config := gs.Configuration()
+
+ targetBlockNum := new(big.Int).SetUint64(config.RoundInterval / config.MinBlockInterval)
+ targetBlockNum.Mul(targetBlockNum, target)
+ targetBlockNum.Quo(targetBlockNum, big.NewInt(100))
+ targetBlockNum.Add(targetBlockNum, roundHeight)
+
+ blockHeight := g.evm.Context.BlockNumber
+ if blockHeight.Cmp(targetBlockNum) < 0 {
+ return nil, errExecutionReverted
+ }
+
+ // Check if next DKG did not success.
+ // Calculate 2f
+ threshold := new(big.Int).Mul(
+ big.NewInt(2),
+ new(big.Int).Div(g.state.DKGSetSize(), big.NewInt(3)))
+
+ // If 2f + 1 of DKG set is finalized, check if DKG succeeded.
+ if g.state.DKGFinalizedsCount(round).Cmp(threshold) > 0 {
+ _, err := g.coreDKGUtils.NewGroupPublicKey(
+ round, int(threshold.Int64()))
+ // DKG success.
+ if err == nil {
+ return nil, errExecutionReverted
+ }
+ switch err {
+ case core.ErrNotReachThreshold, core.ErrInvalidThreshold:
+ default:
+ return nil, errExecutionReverted
+ }
+ }
+ // Clear dkg states for next round.
+ dkgSet := g.getDKGSet(round)
+ g.state.ClearDKGMasterPublicKeys(round)
+ g.state.ClearDKGComplaints(round)
+ g.state.ClearDKGMPKReady(round, dkgSet)
+ g.state.ResetDKGMPKReadysCount(round)
+ g.state.ClearDKGFinalized(round, dkgSet)
+ g.state.ResetDKGFinalizedsCount(round)
+ // Update CRS.
+ prevCRS := g.state.CRS(curRound)
+ for i := uint64(0); i < resetCount.Uint64()+1; i++ {
+ prevCRS = crypto.Keccak256Hash(prevCRS[:])
+ }
+
+ dkgGPK, err := g.coreDKGUtils.NewGroupPublicKey(
+ curRound, int(config.DKGSetSize/3+1))
+ if err != nil {
+ return nil, errExecutionReverted
+ }
+ signature := coreCrypto.Signature{
+ Type: "bls",
+ Signature: newSignedCRS,
+ }
+ if !dkgGPK.VerifySignature(coreCommon.Hash(prevCRS), signature) {
+ return g.penalize()
+ }
+
+ // Save new CRS into state and increase round.
+ newCRS := crypto.Keccak256(newSignedCRS)
+ crs := common.BytesToHash(newCRS)
+
+ g.state.PopCRS()
+ g.state.PushCRS(crs)
+ g.state.emitCRSProposed(round, crs)
+
+ // Increase reset count.
+ g.state.IncDKGResetCount(round)
+
+ g.state.emitDKGReset(round, blockHeight)
+ return nil, nil
+}
+
+// Run executes governance contract.
+func (g *GovernanceContract) Run(evm *EVM, input []byte, contract *vm.Contract) (ret []byte, err error) {
+ if len(input) < 4 {
+ return nil, errExecutionReverted
+ }
+
+ // Initialize contract state.
+ g.evm = evm
+ g.state = GovernanceStateHelper{evm.StateDB}
+ g.contract = contract
+ g.coreDKGUtils.SetState(g.state)
+
+ // Parse input.
+ method, exists := GovernanceABI.Sig2Method[string(input[:4])]
+ if !exists {
+ return nil, errExecutionReverted
+ }
+
+ arguments := input[4:]
+
+ // Dispatch method call.
+ switch method.Name {
+ case "addDKGComplaint":
+ args := struct {
+ Round *big.Int
+ Complaint []byte
+ }{}
+ if err := method.Inputs.Unpack(&args, arguments); err != nil {
+ return nil, errExecutionReverted
+ }
+ return g.addDKGComplaint(args.Round, args.Complaint)
+ case "addDKGMasterPublicKey":
+ args := struct {
+ Round *big.Int
+ PublicKey []byte
+ }{}
+ if err := method.Inputs.Unpack(&args, arguments); err != nil {
+ return nil, errExecutionReverted
+ }
+ return g.addDKGMasterPublicKey(args.Round, args.PublicKey)
+ case "addDKGMPKReady":
+ args := struct {
+ Round *big.Int
+ MPKReady []byte
+ }{}
+ if err := method.Inputs.Unpack(&args, arguments); err != nil {
+ return nil, errExecutionReverted
+ }
+ return g.addDKGMPKReady(args.Round, args.MPKReady)
+ case "addDKGFinalize":
+ args := struct {
+ Round *big.Int
+ Finalize []byte
+ }{}
+ if err := method.Inputs.Unpack(&args, arguments); err != nil {
+ return nil, errExecutionReverted
+ }
+ return g.addDKGFinalize(args.Round, args.Finalize)
+ case "delegate":
+ address := common.Address{}
+ if err := method.Inputs.Unpack(&address, arguments); err != nil {
+ return nil, errExecutionReverted
+ }
+ return g.delegate(address)
+ case "delegatorsLength":
+ address := common.Address{}
+ if err := method.Inputs.Unpack(&address, arguments); err != nil {
+ return nil, errExecutionReverted
+ }
+ res, err := method.Outputs.Pack(g.state.LenDelegators(address))
+ if err != nil {
+ return nil, errExecutionReverted
+ }
+ return res, nil
+ case "nodesLength":
+ res, err := method.Outputs.Pack(g.state.LenNodes())
+ if err != nil {
+ return nil, errExecutionReverted
+ }
+ return res, nil
+ case "payFine":
+ address := common.Address{}
+ if err := method.Inputs.Unpack(&address, arguments); err != nil {
+ return nil, errExecutionReverted
+ }
+ return g.payFine(address)
+ case "proposeCRS":
+ args := struct {
+ Round *big.Int
+ SignedCRS []byte
+ }{}
+ if err := method.Inputs.Unpack(&args, arguments); err != nil {
+ return nil, errExecutionReverted
+ }
+ return g.proposeCRS(args.Round, args.SignedCRS)
+ case "report":
+ args := struct {
+ Type *big.Int
+ Arg1 []byte
+ Arg2 []byte
+ }{}
+ if err := method.Inputs.Unpack(&args, arguments); err != nil {
+ return nil, errExecutionReverted
+ }
+ return g.report(args.Type, args.Arg1, args.Arg2)
+ case "resetDKG":
+ args := struct {
+ NewSignedCRS []byte
+ }{}
+ if err := method.Inputs.Unpack(&args, arguments); err != nil {
+ return nil, errExecutionReverted
+ }
+ return g.resetDKG(args.NewSignedCRS)
+ case "stake":
+ args := struct {
+ PublicKey []byte
+ Name string
+ Email string
+ Location string
+ Url string
+ }{}
+ if err := method.Inputs.Unpack(&args, arguments); err != nil {
+ return nil, errExecutionReverted
+ }
+ return g.stake(args.PublicKey, args.Name, args.Email, args.Location, args.Url)
+ case "transferOwnership":
+ var newOwner common.Address
+ if err := method.Inputs.Unpack(&newOwner, arguments); err != nil {
+ return nil, errExecutionReverted
+ }
+ return g.transferOwnership(newOwner)
+ case "undelegate":
+ address := common.Address{}
+ if err := method.Inputs.Unpack(&address, arguments); err != nil {
+ return nil, errExecutionReverted
+ }
+ return g.undelegate(address)
+ case "unstake":
+ return g.unstake()
+ case "updateConfiguration":
+ var cfg rawConfigStruct
+ if err := method.Inputs.Unpack(&cfg, arguments); err != nil {
+ return nil, errExecutionReverted
+ }
+ return g.updateConfiguration(&cfg)
+ case "withdraw":
+ address := common.Address{}
+ if err := method.Inputs.Unpack(&address, arguments); err != nil {
+ return nil, errExecutionReverted
+ }
+ return g.withdraw(address)
+
+ // --------------------------------
+ // Solidity auto generated methods.
+ // --------------------------------
+
+ case "blockGasLimit":
+ res, err := method.Outputs.Pack(g.state.BlockGasLimit())
+ if err != nil {
+ return nil, errExecutionReverted
+ }
+ return res, nil
+ case "crs":
+ round := new(big.Int)
+ if err := method.Inputs.Unpack(&round, arguments); err != nil {
+ return nil, errExecutionReverted
+ }
+ res, err := method.Outputs.Pack(g.state.CRS(round))
+ if err != nil {
+ return nil, errExecutionReverted
+ }
+ return res, nil
+ case "delegators":
+ nodeAddr, index := common.Address{}, new(big.Int)
+ args := []interface{}{&nodeAddr, &index}
+ if err := method.Inputs.Unpack(&args, arguments); err != nil {
+ return nil, errExecutionReverted
+ }
+ delegator := g.state.Delegator(nodeAddr, index)
+ res, err := method.Outputs.Pack(delegator.Owner, delegator.Value, delegator.UndelegatedAt)
+ if err != nil {
+ return nil, errExecutionReverted
+ }
+ return res, nil
+ case "delegatorsOffset":
+ nodeAddr, delegatorAddr := common.Address{}, common.Address{}
+ args := []interface{}{&nodeAddr, &delegatorAddr}
+ if err := method.Inputs.Unpack(&args, arguments); err != nil {
+ return nil, errExecutionReverted
+ }
+ res, err := method.Outputs.Pack(g.state.DelegatorsOffset(nodeAddr, delegatorAddr))
+ if err != nil {
+ return nil, errExecutionReverted
+ }
+ return res, nil
+ case "dkgComplaints":
+ round, index := new(big.Int), new(big.Int)
+ args := []interface{}{&round, &index}
+ if err := method.Inputs.Unpack(&args, arguments); err != nil {
+ return nil, errExecutionReverted
+ }
+ complaints := g.state.DKGComplaints(round)
+ if int(index.Uint64()) >= len(complaints) {
+ return nil, errExecutionReverted
+ }
+ complaint := complaints[index.Uint64()]
+ res, err := method.Outputs.Pack(complaint)
+ if err != nil {
+ return nil, errExecutionReverted
+ }
+ return res, nil
+ case "dkgReadys":
+ round, addr := new(big.Int), common.Address{}
+ args := []interface{}{&round, &addr}
+ if err := method.Inputs.Unpack(&args, arguments); err != nil {
+ return nil, errExecutionReverted
+ }
+ ready := g.state.DKGMPKReady(round, addr)
+ res, err := method.Outputs.Pack(ready)
+ if err != nil {
+ return nil, errExecutionReverted
+ }
+ return res, nil
+ case "dkgReadysCount":
+ round := new(big.Int)
+ if err := method.Inputs.Unpack(&round, arguments); err != nil {
+ return nil, errExecutionReverted
+ }
+ count := g.state.DKGMPKReadysCount(round)
+ res, err := method.Outputs.Pack(count)
+ if err != nil {
+ return nil, errExecutionReverted
+ }
+ return res, nil
+
+ case "dkgFinalizeds":
+ round, addr := new(big.Int), common.Address{}
+ args := []interface{}{&round, &addr}
+ if err := method.Inputs.Unpack(&args, arguments); err != nil {
+ return nil, errExecutionReverted
+ }
+ finalized := g.state.DKGFinalized(round, addr)
+ res, err := method.Outputs.Pack(finalized)
+ if err != nil {
+ return nil, errExecutionReverted
+ }
+ return res, nil
+ case "dkgFinalizedsCount":
+ round := new(big.Int)
+ if err := method.Inputs.Unpack(&round, arguments); err != nil {
+ return nil, errExecutionReverted
+ }
+ count := g.state.DKGFinalizedsCount(round)
+ res, err := method.Outputs.Pack(count)
+ if err != nil {
+ return nil, errExecutionReverted
+ }
+ return res, nil
+ case "dkgMasterPublicKeys":
+ round, index := new(big.Int), new(big.Int)
+ args := []interface{}{&round, &index}
+ if err := method.Inputs.Unpack(&args, arguments); err != nil {
+ return nil, errExecutionReverted
+ }
+ mpks := g.state.DKGMasterPublicKeys(round)
+ if int(index.Uint64()) >= len(mpks) {
+ return nil, errExecutionReverted
+ }
+ mpk := mpks[index.Uint64()]
+ res, err := method.Outputs.Pack(mpk)
+ if err != nil {
+ return nil, errExecutionReverted
+ }
+ return res, nil
+ case "dkgSetSize":
+ res, err := method.Outputs.Pack(g.state.DKGSetSize())
+ if err != nil {
+ return nil, errExecutionReverted
+ }
+ return res, nil
+ case "finedRecords":
+ record := Bytes32{}
+ if err := method.Inputs.Unpack(&record, arguments); err != nil {
+ return nil, errExecutionReverted
+ }
+ value := g.state.FineRecords(record)
+ res, err := method.Outputs.Pack(value)
+ if err != nil {
+ return nil, errExecutionReverted
+ }
+ return res, nil
+ case "fineValues":
+ index := new(big.Int)
+ if err := method.Inputs.Unpack(&index, arguments); err != nil {
+ return nil, errExecutionReverted
+ }
+ value := g.state.FineValue(index)
+ res, err := method.Outputs.Pack(value)
+ if err != nil {
+ return nil, errExecutionReverted
+ }
+ return res, nil
+ case "k":
+ res, err := method.Outputs.Pack(g.state.K())
+ if err != nil {
+ return nil, errExecutionReverted
+ }
+ return res, nil
+ case "lambdaBA":
+ res, err := method.Outputs.Pack(g.state.LambdaBA())
+ if err != nil {
+ return nil, errExecutionReverted
+ }
+ return res, nil
+ case "lambdaDKG":
+ res, err := method.Outputs.Pack(g.state.LambdaDKG())
+ if err != nil {
+ return nil, errExecutionReverted
+ }
+ return res, nil
+ case "lastHalvedAmount":
+ res, err := method.Outputs.Pack(g.state.LastHalvedAmount())
+ if err != nil {
+ return nil, errExecutionReverted
+ }
+ return res, nil
+ case "lockupPeriod":
+ res, err := method.Outputs.Pack(g.state.LockupPeriod())
+ if err != nil {
+ return nil, errExecutionReverted
+ }
+ return res, nil
+ case "minBlockInterval":
+ res, err := method.Outputs.Pack(g.state.MinBlockInterval())
+ if err != nil {
+ return nil, errExecutionReverted
+ }
+ return res, nil
+ case "miningVelocity":
+ res, err := method.Outputs.Pack(g.state.MiningVelocity())
+ if err != nil {
+ return nil, errExecutionReverted
+ }
+ return res, nil
+ case "minStake":
+ res, err := method.Outputs.Pack(g.state.MinStake())
+ if err != nil {
+ return nil, errExecutionReverted
+ }
+ return res, nil
+ case "nextHalvingSupply":
+ res, err := method.Outputs.Pack(g.state.NextHalvingSupply())
+ if err != nil {
+ return nil, errExecutionReverted
+ }
+ return res, nil
+ case "numChains":
+ res, err := method.Outputs.Pack(g.state.NumChains())
+ if err != nil {
+ return nil, errExecutionReverted
+ }
+ return res, nil
+ case "nodes":
+ index := new(big.Int)
+ if err := method.Inputs.Unpack(&index, arguments); err != nil {
+ return nil, errExecutionReverted
+ }
+ info := g.state.Node(index)
+ res, err := method.Outputs.Pack(
+ info.Owner, info.PublicKey, info.Staked, info.Fined,
+ info.Name, info.Email, info.Location, info.Url)
+ if err != nil {
+ return nil, errExecutionReverted
+ }
+ return res, nil
+ case "nodesOffsetByAddress":
+ address := common.Address{}
+ if err := method.Inputs.Unpack(&address, arguments); err != nil {
+ return nil, errExecutionReverted
+ }
+ res, err := method.Outputs.Pack(g.state.NodesOffsetByAddress(address))
+ if err != nil {
+ return nil, errExecutionReverted
+ }
+ return res, nil
+ case "nodesOffsetByID":
+ var id Bytes32
+ if err := method.Inputs.Unpack(&id, arguments); err != nil {
+ return nil, errExecutionReverted
+ }
+ res, err := method.Outputs.Pack(g.state.NodesOffsetByID(id))
+ if err != nil {
+ return nil, errExecutionReverted
+ }
+ return res, nil
+ case "notarySetSize":
+ res, err := method.Outputs.Pack(g.state.NotarySetSize())
+ if err != nil {
+ return nil, errExecutionReverted
+ }
+ return res, nil
+ case "owner":
+ res, err := method.Outputs.Pack(g.state.Owner())
+ if err != nil {
+ return nil, errExecutionReverted
+ }
+ return res, nil
+ case "phiRatio":
+ res, err := method.Outputs.Pack(g.state.PhiRatio())
+ if err != nil {
+ return nil, errExecutionReverted
+ }
+ return res, nil
+ case "roundHeight":
+ round := new(big.Int)
+ if err := method.Inputs.Unpack(&round, arguments); err != nil {
+ return nil, errExecutionReverted
+ }
+ res, err := method.Outputs.Pack(g.state.RoundHeight(round))
+ if err != nil {
+ return nil, errExecutionReverted
+ }
+ return res, nil
+ case "roundInterval":
+ res, err := method.Outputs.Pack(g.state.RoundInterval())
+ if err != nil {
+ return nil, errExecutionReverted
+ }
+ return res, nil
+ case "totalStaked":
+ res, err := method.Outputs.Pack(g.state.TotalStaked())
+ if err != nil {
+ return nil, errExecutionReverted
+ }
+ return res, nil
+ case "totalSupply":
+ res, err := method.Outputs.Pack(g.state.TotalSupply())
+ if err != nil {
+ return nil, errExecutionReverted
+ }
+ return res, nil
+ case "DKGResetCount":
+ round := new(big.Int)
+ if err := method.Inputs.Unpack(&round, arguments); err != nil {
+ return nil, errExecutionReverted
+ }
+ res, err := method.Outputs.Pack(g.state.DKGResetCount(round))
+ if err != nil {
+ return nil, errExecutionReverted
+ }
+ return res, nil
+ }
+ return nil, errExecutionReverted
+}
+
func (g *GovernanceContract) transferOwnership(newOwner common.Address) ([]byte, error) {
// Only owner can update configuration.
if g.contract.Caller() != g.state.Owner() {
@@ -2172,27 +2393,183 @@ func (g *GovernanceContract) transferOwnership(newOwner common.Address) ([]byte,
return nil, nil
}
-func (g *GovernanceContract) snapshotRound(round, height *big.Int) ([]byte, error) {
- // Validate if this mapping is correct. Only block proposer need to verify this.
- if g.evm.IsBlockProposer() {
- realHeight, ok := g.evm.GetRoundHeight(round.Uint64())
- if !ok {
- return g.penalize()
- }
+func PackProposeCRS(round uint64, signedCRS []byte) ([]byte, error) {
+ method := GovernanceABI.Name2Method["proposeCRS"]
+ res, err := method.Inputs.Pack(big.NewInt(int64(round)), signedCRS)
+ if err != nil {
+ return nil, err
+ }
+ data := append(method.Id(), res...)
+ return data, nil
+}
- if height.Cmp(new(big.Int).SetUint64(realHeight)) != 0 {
- return g.penalize()
- }
+func PackAddDKGMasterPublicKey(round uint64, mpk *dkgTypes.MasterPublicKey) ([]byte, error) {
+ method := GovernanceABI.Name2Method["addDKGMasterPublicKey"]
+ encoded, err := rlp.EncodeToBytes(mpk)
+ if err != nil {
+ return nil, err
+ }
+ res, err := method.Inputs.Pack(big.NewInt(int64(round)), encoded)
+ if err != nil {
+ return nil, err
+ }
+ data := append(method.Id(), res...)
+ return data, nil
+}
+
+func PackAddDKGMPKReady(round uint64, ready *dkgTypes.MPKReady) ([]byte, error) {
+ method := GovernanceABI.Name2Method["addDKGMPKReady"]
+ encoded, err := rlp.EncodeToBytes(ready)
+ if err != nil {
+ return nil, err
+ }
+ res, err := method.Inputs.Pack(big.NewInt(int64(round)), encoded)
+ if err != nil {
+ return nil, err
+ }
+ data := append(method.Id(), res...)
+ return data, nil
+}
+
+func PackAddDKGComplaint(round uint64, complaint *dkgTypes.Complaint) ([]byte, error) {
+ method := GovernanceABI.Name2Method["addDKGComplaint"]
+ encoded, err := rlp.EncodeToBytes(complaint)
+ if err != nil {
+ return nil, err
+ }
+
+ res, err := method.Inputs.Pack(big.NewInt(int64(round)), encoded)
+ if err != nil {
+ return nil, err
}
+ data := append(method.Id(), res...)
+ return data, nil
+}
- // Only allow updating the next round.
- nextRound := g.state.LenRoundHeight()
- if round.Cmp(nextRound) != 0 {
- // No need to penalize, since the only possibility at this point is the
- // round height is already snapshoted.
+func PackAddDKGFinalize(round uint64, final *dkgTypes.Finalize) ([]byte, error) {
+ method := GovernanceABI.Name2Method["addDKGFinalize"]
+ encoded, err := rlp.EncodeToBytes(final)
+ if err != nil {
+ return nil, err
+ }
+
+ res, err := method.Inputs.Pack(big.NewInt(int64(round)), encoded)
+ if err != nil {
+ return nil, err
+ }
+ data := append(method.Id(), res...)
+ return data, nil
+}
+
+func PackReportForkVote(vote1, vote2 *coreTypes.Vote) ([]byte, error) {
+ method := GovernanceABI.Name2Method["report"]
+
+ vote1Bytes, err := rlp.EncodeToBytes(vote1)
+ if err != nil {
+ return nil, err
+ }
+
+ vote2Bytes, err := rlp.EncodeToBytes(vote2)
+ if err != nil {
+ return nil, err
+ }
+
+ res, err := method.Inputs.Pack(big.NewInt(ReportTypeForkVote), vote1Bytes, vote2Bytes)
+ if err != nil {
+ return nil, err
+ }
+
+ data := append(method.Id(), res...)
+ return data, nil
+}
+
+func PackReportForkBlock(block1, block2 *coreTypes.Block) ([]byte, error) {
+ method := GovernanceABI.Name2Method["report"]
+
+ block1Bytes, err := rlp.EncodeToBytes(block1)
+ if err != nil {
+ return nil, err
+ }
+
+ block2Bytes, err := rlp.EncodeToBytes(block2)
+ if err != nil {
+ return nil, err
+ }
+
+ res, err := method.Inputs.Pack(big.NewInt(ReportTypeForkBlock), block1Bytes, block2Bytes)
+ if err != nil {
+ return nil, err
+ }
+
+ data := append(method.Id(), res...)
+ return data, nil
+}
+
+// NodeInfoOracleContract representing a oracle providing the node information.
+type NodeInfoOracleContract struct {
+}
+
+func (g *NodeInfoOracleContract) Run(evm *EVM, input []byte, contract *vm.Contract) (ret []byte, err error) {
+ if len(input) < 4 {
return nil, errExecutionReverted
}
- g.state.PushRoundHeight(height)
- return nil, nil
+ // Parse input.
+ method, exists := NodeInfoOracleABI.Sig2Method[string(input[:4])]
+ if !exists {
+ return nil, errExecutionReverted
+ }
+
+ arguments := input[4:]
+
+ // Dispatch method call.
+ switch method.Name {
+ case "delegators":
+ round, nodeAddr, index := new(big.Int), common.Address{}, new(big.Int)
+ args := []interface{}{&round, &nodeAddr, &index}
+ if err := method.Inputs.Unpack(&args, arguments); err != nil {
+ return nil, errExecutionReverted
+ }
+ state, err := getConfigState(evm, round)
+ if err != nil {
+ return nil, err
+ }
+ delegator := state.Delegator(nodeAddr, index)
+ res, err := method.Outputs.Pack(delegator.Owner, delegator.Value, delegator.UndelegatedAt)
+ if err != nil {
+ return nil, errExecutionReverted
+ }
+ return res, nil
+ case "delegatorsLength":
+ round, address := new(big.Int), common.Address{}
+ args := []interface{}{&round, &address}
+ if err := method.Inputs.Unpack(&args, arguments); err != nil {
+ return nil, errExecutionReverted
+ }
+ state, err := getConfigState(evm, round)
+ if err != nil {
+ return nil, err
+ }
+ res, err := method.Outputs.Pack(state.LenDelegators(address))
+ if err != nil {
+ return nil, errExecutionReverted
+ }
+ return res, nil
+ case "delegatorsOffset":
+ round, nodeAddr, delegatorAddr := new(big.Int), common.Address{}, common.Address{}
+ args := []interface{}{&round, &nodeAddr, &delegatorAddr}
+ if err := method.Inputs.Unpack(&args, arguments); err != nil {
+ return nil, errExecutionReverted
+ }
+ state, err := getConfigState(evm, round)
+ if err != nil {
+ return nil, err
+ }
+ res, err := method.Outputs.Pack(state.DelegatorsOffset(nodeAddr, delegatorAddr))
+ if err != nil {
+ return nil, errExecutionReverted
+ }
+ return res, nil
+ }
+ return nil, errExecutionReverted
}
diff --git a/core/vm/evm/governance_test.go b/core/vm/evm/oracle_contracts_test.go
index 5a82c7f1a..632d1dce3 100644
--- a/core/vm/evm/governance_test.go
+++ b/core/vm/evm/oracle_contracts_test.go
@@ -47,7 +47,10 @@ func init() {
}
func randomBytes(minLength, maxLength int32) []byte {
- length := rand.Int31()%(maxLength-minLength) + minLength
+ length := minLength
+ if maxLength != minLength {
+ length += rand.Int31() % (maxLength - minLength)
+ }
b := make([]byte, length)
for i := range b {
b[i] = byte(65 + rand.Int31()%60)
@@ -70,7 +73,7 @@ func (g *GovernanceStateHelperTestSuite) SetupTest() {
g.s = &GovernanceStateHelper{statedb}
}
-func (g *GovernanceStateHelperTestSuite) TestReadWriteBytes() {
+func (g *GovernanceStateHelperTestSuite) TestReadWriteEraseBytes() {
for i := 0; i < 100; i++ {
// Short bytes.
loc := big.NewInt(rand.Int63())
@@ -78,6 +81,9 @@ func (g *GovernanceStateHelperTestSuite) TestReadWriteBytes() {
g.s.writeBytes(loc, data)
read := g.s.readBytes(loc)
g.Require().Equal(0, bytes.Compare(data, read))
+ g.s.eraseBytes(loc)
+ read = g.s.readBytes(loc)
+ g.Require().Len(read, 0)
// long bytes.
loc = big.NewInt(rand.Int63())
@@ -85,6 +91,31 @@ func (g *GovernanceStateHelperTestSuite) TestReadWriteBytes() {
g.s.writeBytes(loc, data)
read = g.s.readBytes(loc)
g.Require().Equal(0, bytes.Compare(data, read))
+ g.s.eraseBytes(loc)
+ read = g.s.readBytes(loc)
+ g.Require().Len(read, 0)
+ }
+}
+
+func (g *GovernanceStateHelperTestSuite) TestReadWriteErase2DArray() {
+ for i := 0; i < 50; i++ {
+ loc := big.NewInt(rand.Int63())
+ for j := 0; j < 50; j++ {
+ idx := big.NewInt(int64(j))
+ data := make([][]byte, 30)
+ for key := range data {
+ data[key] = randomBytes(3, 32)
+ g.s.appendTo2DByteArray(loc, idx, data[key])
+ }
+ read := g.s.read2DByteArray(loc, idx)
+ g.Require().Len(read, len(data))
+ for key := range data {
+ g.Require().Equal(0, bytes.Compare(data[key], read[key]))
+ }
+ g.s.erase2DByteArray(loc, idx)
+ read = g.s.read2DByteArray(loc, idx)
+ g.Require().Len(read, 0)
+ }
}
}
@@ -92,16 +123,17 @@ func TestGovernanceStateHelper(t *testing.T) {
suite.Run(t, new(GovernanceStateHelperTestSuite))
}
-type GovernanceContractTestSuite struct {
+type OracleContractsTestSuite struct {
suite.Suite
+ context vm.Context
config *params.DexconConfig
memDB *ethdb.MemDatabase
stateDB *state.StateDB
s *GovernanceStateHelper
}
-func (g *GovernanceContractTestSuite) SetupTest() {
+func (g *OracleContractsTestSuite) SetupTest() {
memDB := ethdb.NewMemDatabase()
stateDB, err := state.New(common.Hash{}, state.NewDatabase(memDB))
if err != nil {
@@ -116,6 +148,7 @@ func (g *GovernanceContractTestSuite) SetupTest() {
config.NextHalvingSupply = new(big.Int).Mul(big.NewInt(1e18), big.NewInt(2.5e9))
config.LastHalvedAmount = new(big.Int).Mul(big.NewInt(1e18), big.NewInt(1.5e9))
config.MiningVelocity = 0.1875
+ config.DKGSetSize = 7
g.config = config
@@ -136,21 +169,8 @@ func (g *GovernanceContractTestSuite) SetupTest() {
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(2e6)))
- return privKey, address
-}
-func (g *GovernanceContractTestSuite) call(caller common.Address, input []byte, value *big.Int) ([]byte, error) {
- context := vm.Context{
+ g.context = vm.Context{
CanTransfer: func(db vm.StateDB, addr common.Address, amount *big.Int) bool {
return db.GetBalance(addr).Cmp(amount) >= 0
},
@@ -169,41 +189,65 @@ func (g *GovernanceContractTestSuite) call(caller common.Address, input []byte,
}
return 0, false
},
- Time: big.NewInt(time.Now().UnixNano() / 1000000),
+ StateAtNumber: func(n uint64) (*state.StateDB, error) {
+ return g.stateDB, nil
+ },
BlockNumber: big.NewInt(0),
}
- evm := NewEVM(context, g.stateDB, params.TestChainConfig, Config{IsBlockProposer: true})
- ret, _, err := evm.Call(vm.AccountRef(caller), GovernanceContractAddress, input, 10000000, value)
+}
+
+func (g *OracleContractsTestSuite) TearDownTest() {
+ OracleContracts[GovernanceContractAddress].(*GovernanceContract).coreDKGUtils = &defaultCoreDKGUtils{}
+}
+
+func (g *OracleContractsTestSuite) 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(2e6)))
+ return privKey, address
+}
+
+func (g *OracleContractsTestSuite) call(
+ contractAddr common.Address, caller common.Address, input []byte, value *big.Int) ([]byte, error) {
+
+ g.context.Time = big.NewInt(time.Now().UnixNano() / 1000000)
+
+ evm := NewEVM(g.context, g.stateDB, params.TestChainConfig, Config{IsBlockProposer: true})
+ ret, _, err := evm.Call(vm.AccountRef(caller), contractAddr, input, 10000000, value)
return ret, err
}
-func (g *GovernanceContractTestSuite) TestTransferOwnership() {
+func (g *OracleContractsTestSuite) TestTransferOwnership() {
_, addr := g.newPrefundAccount()
- input, err := abiObject.Pack("transferOwnership", addr)
+ input, err := GovernanceABI.ABI.Pack("transferOwnership", addr)
g.Require().NoError(err)
// Call with non-owner.
- _, err = g.call(addr, input, big.NewInt(0))
+ _, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0))
g.Require().NotNil(err)
// Call with owner.
- _, err = g.call(g.config.Owner, input, big.NewInt(0))
+ _, err = g.call(GovernanceContractAddress, g.config.Owner, input, big.NewInt(0))
g.Require().NoError(err)
g.Require().Equal(addr, g.s.Owner())
}
-func (g *GovernanceContractTestSuite) TestStakeUnstakeWithoutExtraDelegators() {
+func (g *OracleContractsTestSuite) TestStakeUnstakeWithoutExtraDelegators() {
privKey, addr := g.newPrefundAccount()
pk := crypto.FromECDSAPub(&privKey.PublicKey)
// Stake.
amount := new(big.Int).Mul(big.NewInt(1e18), big.NewInt(1e6))
balanceBeforeStake := g.stateDB.GetBalance(addr)
- input, err := abiObject.Pack("stake", pk, "Test1", "test1@dexon.org", "Taipei, Taiwan", "https://dexon.org")
+ input, err := GovernanceABI.ABI.Pack("stake", pk, "Test1", "test1@dexon.org", "Taipei, Taiwan", "https://dexon.org")
g.Require().NoError(err)
- _, err = g.call(addr, input, amount)
+ _, err = g.call(GovernanceContractAddress, addr, input, amount)
g.Require().NoError(err)
g.Require().Equal(1, int(g.s.LenNodes().Uint64()))
@@ -216,13 +260,13 @@ func (g *GovernanceContractTestSuite) TestStakeUnstakeWithoutExtraDelegators() {
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)
+ _, err = g.call(GovernanceContractAddress, addr, input, amount)
g.Require().NotNil(err)
// Unstake.
- input, err = abiObject.Pack("unstake")
+ input, err = GovernanceABI.ABI.Pack("unstake")
g.Require().NoError(err)
- _, err = g.call(addr, input, big.NewInt(0))
+ _, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0))
g.Require().NoError(err)
g.Require().Equal(0, len(g.s.QualifiedNodes()))
g.Require().Equal(1, int(g.s.LenDelegators(addr).Uint64()))
@@ -234,9 +278,9 @@ func (g *GovernanceContractTestSuite) TestStakeUnstakeWithoutExtraDelegators() {
// Wait for lockup time than withdraw.
time.Sleep(time.Second * 2)
- input, err = abiObject.Pack("withdraw", addr)
+ input, err = GovernanceABI.ABI.Pack("withdraw", addr)
g.Require().NoError(err)
- _, err = g.call(addr, input, big.NewInt(0))
+ _, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0))
g.Require().NoError(err)
g.Require().Equal(0, len(g.s.QualifiedNodes()))
@@ -248,26 +292,26 @@ func (g *GovernanceContractTestSuite) TestStakeUnstakeWithoutExtraDelegators() {
// 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")
+ input, err = GovernanceABI.ABI.Pack("stake", pk2, "Test2", "test2@dexon.org", "Taipei, Taiwan", "https://dexon.org")
g.Require().NoError(err)
- _, err = g.call(addr2, input, amount)
+ _, err = g.call(GovernanceContractAddress, addr2, input, amount)
g.Require().NoError(err)
g.Require().Equal("Test2", g.s.Node(big.NewInt(0)).Name)
g.Require().Equal(0, int(g.s.NodesOffsetByAddress(addr2).Int64()))
// 1st node Stake.
- input, err = abiObject.Pack("stake", pk, "Test1", "test1@dexon.org", "Taipei, Taiwan", "https://dexon.org")
+ input, err = GovernanceABI.ABI.Pack("stake", pk, "Test1", "test1@dexon.org", "Taipei, Taiwan", "https://dexon.org")
g.Require().NoError(err)
- _, err = g.call(addr, input, amount)
+ _, err = g.call(GovernanceContractAddress, addr, input, amount)
g.Require().NoError(err)
g.Require().Equal(2, len(g.s.QualifiedNodes()))
g.Require().Equal(new(big.Int).Mul(amount, big.NewInt(2)).String(), g.s.TotalStaked().String())
// 2nd node Unstake.
- input, err = abiObject.Pack("unstake")
+ input, err = GovernanceABI.ABI.Pack("unstake")
g.Require().NoError(err)
- _, err = g.call(addr2, input, big.NewInt(0))
+ _, err = g.call(GovernanceContractAddress, addr2, input, big.NewInt(0))
g.Require().NoError(err)
node = g.s.Node(big.NewInt(0))
g.Require().Equal("Test2", node.Name)
@@ -276,9 +320,9 @@ func (g *GovernanceContractTestSuite) TestStakeUnstakeWithoutExtraDelegators() {
g.Require().Equal(amount.String(), g.s.TotalStaked().String())
time.Sleep(time.Second * 2)
- input, err = abiObject.Pack("withdraw", addr2)
+ input, err = GovernanceABI.ABI.Pack("withdraw", addr2)
g.Require().NoError(err)
- _, err = g.call(addr2, input, big.NewInt(0))
+ _, err = g.call(GovernanceContractAddress, addr2, input, big.NewInt(0))
g.Require().NoError(err)
g.Require().Equal(1, len(g.s.QualifiedNodes()))
@@ -287,17 +331,17 @@ func (g *GovernanceContractTestSuite) TestStakeUnstakeWithoutExtraDelegators() {
g.Require().Equal(-1, int(g.s.NodesOffsetByAddress(addr2).Int64()))
// 1st node Unstake.
- input, err = abiObject.Pack("unstake")
+ input, err = GovernanceABI.ABI.Pack("unstake")
g.Require().NoError(err)
- _, err = g.call(addr, input, big.NewInt(0))
+ _, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0))
g.Require().NoError(err)
g.Require().Equal(0, len(g.s.QualifiedNodes()))
g.Require().Equal(big.NewInt(0).String(), g.s.TotalStaked().String())
time.Sleep(time.Second * 2)
- input, err = abiObject.Pack("withdraw", addr)
+ input, err = GovernanceABI.ABI.Pack("withdraw", addr)
g.Require().NoError(err)
- _, err = g.call(addr, input, big.NewInt(0))
+ _, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0))
g.Require().NoError(err)
g.Require().Equal(0, int(g.s.LenNodes().Uint64()))
@@ -310,15 +354,15 @@ func (g *GovernanceContractTestSuite) TestStakeUnstakeWithoutExtraDelegators() {
g.Require().Equal(big.NewInt(1), g.stateDB.GetBalance(GovernanceContractAddress))
}
-func (g *GovernanceContractTestSuite) TestDelegateUndelegate() {
+func (g *OracleContractsTestSuite) 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")
+ input, err := GovernanceABI.ABI.Pack("stake", pk, "Test1", "test1@dexon.org", "Taipei, Taiwan", "https://dexon.org")
g.Require().NoError(err)
ownerStaked := new(big.Int).Mul(big.NewInt(1e18), big.NewInt(5e5))
- _, err = g.call(addr, input, ownerStaked)
+ _, err = g.call(GovernanceContractAddress, addr, input, ownerStaked)
g.Require().NoError(err)
g.Require().Equal(0, len(g.s.QualifiedNodes()))
g.Require().Equal(addr, g.s.Delegator(addr, big.NewInt(0)).Owner)
@@ -329,10 +373,10 @@ func (g *GovernanceContractTestSuite) TestDelegateUndelegate() {
balanceBeforeDelegate := g.stateDB.GetBalance(addrDelegator)
amount := new(big.Int).Mul(big.NewInt(1e18), big.NewInt(3e5))
- input, err = abiObject.Pack("delegate", addr)
+ input, err = GovernanceABI.ABI.Pack("delegate", addr)
g.Require().NoError(err)
- _, err = g.call(addrDelegator, input, amount)
+ _, err = g.call(GovernanceContractAddress, addrDelegator, input, amount)
g.Require().NoError(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)
@@ -341,7 +385,7 @@ func (g *GovernanceContractTestSuite) TestDelegateUndelegate() {
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))
+ _, err = g.call(GovernanceContractAddress, addrDelegator, input, big.NewInt(1e18))
g.Require().NotNil(err)
// Not yet qualified.
@@ -349,7 +393,7 @@ func (g *GovernanceContractTestSuite) TestDelegateUndelegate() {
// 2nd delegator delegate to 1st node.
_, addrDelegator2 := g.newPrefundAccount()
- _, err = g.call(addrDelegator2, input, amount)
+ _, err = g.call(GovernanceContractAddress, addrDelegator2, input, amount)
g.Require().NoError(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)
@@ -363,21 +407,21 @@ func (g *GovernanceContractTestSuite) TestDelegateUndelegate() {
// Undelegate addrDelegator.
balanceBeforeUnDelegate := g.stateDB.GetBalance(addrDelegator)
- input, err = abiObject.Pack("undelegate", addr)
+ input, err = GovernanceABI.ABI.Pack("undelegate", addr)
g.Require().NoError(err)
- _, err = g.call(addrDelegator, input, big.NewInt(0))
+ _, err = g.call(GovernanceContractAddress, addrDelegator, input, big.NewInt(0))
g.Require().Equal(new(big.Int).Add(amount, ownerStaked), g.s.Node(big.NewInt(0)).Staked)
g.Require().Equal(g.s.Node(big.NewInt(0)).Staked.String(), g.s.TotalStaked().String())
g.Require().NoError(err)
// Undelegate the second time should fail.
- _, err = g.call(addrDelegator, input, big.NewInt(0))
+ _, err = g.call(GovernanceContractAddress, addrDelegator, input, big.NewInt(0))
g.Require().Error(err)
// Withdraw within lockup time should fail.
- input, err = abiObject.Pack("withdraw", addr)
+ input, err = GovernanceABI.ABI.Pack("withdraw", addr)
g.Require().NoError(err)
- _, err = g.call(addrDelegator, input, big.NewInt(0))
+ _, err = g.call(GovernanceContractAddress, addrDelegator, input, big.NewInt(0))
g.Require().NotNil(err)
g.Require().Equal(3, int(g.s.LenDelegators(addr).Uint64()))
@@ -386,9 +430,9 @@ func (g *GovernanceContractTestSuite) TestDelegateUndelegate() {
// Wait for lockup time than withdraw.
time.Sleep(time.Second * 2)
- input, err = abiObject.Pack("withdraw", addr)
+ input, err = GovernanceABI.ABI.Pack("withdraw", addr)
g.Require().NoError(err)
- _, err = g.call(addrDelegator, input, big.NewInt(0))
+ _, err = g.call(GovernanceContractAddress, addrDelegator, input, big.NewInt(0))
g.Require().NoError(err)
g.Require().Equal(2, int(g.s.LenDelegators(addr).Uint64()))
@@ -397,16 +441,16 @@ func (g *GovernanceContractTestSuite) TestDelegateUndelegate() {
// Withdraw when their is no delegation should fail.
time.Sleep(time.Second)
- input, err = abiObject.Pack("withdraw", addr)
+ input, err = GovernanceABI.ABI.Pack("withdraw", addr)
g.Require().NoError(err)
- _, err = g.call(addrDelegator, input, big.NewInt(0))
+ _, err = g.call(GovernanceContractAddress, addrDelegator, input, big.NewInt(0))
g.Require().Error(err)
// Undelegate addrDelegator2.
balanceBeforeUnDelegate = g.stateDB.GetBalance(addrDelegator2)
- input, err = abiObject.Pack("undelegate", addr)
+ input, err = GovernanceABI.ABI.Pack("undelegate", addr)
g.Require().NoError(err)
- _, err = g.call(addrDelegator2, input, big.NewInt(0))
+ _, err = g.call(GovernanceContractAddress, addrDelegator2, input, big.NewInt(0))
g.Require().NoError(err)
g.Require().Equal(ownerStaked, g.s.Node(big.NewInt(0)).Staked)
@@ -414,9 +458,9 @@ func (g *GovernanceContractTestSuite) TestDelegateUndelegate() {
// Wait for lockup time than withdraw.
time.Sleep(time.Second * 2)
- input, err = abiObject.Pack("withdraw", addr)
+ input, err = GovernanceABI.ABI.Pack("withdraw", addr)
g.Require().NoError(err)
- _, err = g.call(addrDelegator2, input, big.NewInt(0))
+ _, err = g.call(GovernanceContractAddress, addrDelegator2, input, big.NewInt(0))
g.Require().NoError(err)
g.Require().Equal(1, int(g.s.LenDelegators(addr).Uint64()))
@@ -430,31 +474,31 @@ func (g *GovernanceContractTestSuite) TestDelegateUndelegate() {
g.Require().Equal(1, int(g.s.LenNodes().Uint64()))
g.Require().Equal(1, int(g.s.LenDelegators(addr).Uint64()))
- input, err = abiObject.Pack("undelegate", addr)
+ input, err = GovernanceABI.ABI.Pack("undelegate", addr)
g.Require().NoError(err)
- _, err = g.call(addr, input, big.NewInt(0))
+ _, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0))
g.Require().NoError(err)
g.Require().Equal(big.NewInt(0).String(), g.s.Node(big.NewInt(0)).Staked.String())
g.Require().Equal(big.NewInt(0).String(), g.s.TotalStaked().String())
time.Sleep(time.Second * 2)
- input, err = abiObject.Pack("withdraw", addr)
+ input, err = GovernanceABI.ABI.Pack("withdraw", addr)
g.Require().NoError(err)
- _, err = g.call(addr, input, big.NewInt(0))
+ _, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0))
g.Require().Equal(0, int(g.s.LenNodes().Uint64()))
g.Require().Equal(0, int(g.s.LenDelegators(addr).Uint64()))
}
-func (g *GovernanceContractTestSuite) TestFine() {
+func (g *OracleContractsTestSuite) TestFine() {
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")
+ input, err := GovernanceABI.ABI.Pack("stake", pk, "Test1", "test1@dexon.org", "Taipei, Taiwan", "https://dexon.org")
g.Require().NoError(err)
ownerStaked := new(big.Int).Mul(big.NewInt(1e18), big.NewInt(5e5))
- _, err = g.call(addr, input, ownerStaked)
+ _, err = g.call(GovernanceContractAddress, addr, input, ownerStaked)
g.Require().NoError(err)
g.Require().Equal(0, len(g.s.QualifiedNodes()))
g.Require().Equal(addr, g.s.Delegator(addr, big.NewInt(0)).Owner)
@@ -465,10 +509,10 @@ func (g *GovernanceContractTestSuite) TestFine() {
balanceBeforeDelegate := g.stateDB.GetBalance(addrDelegator)
amount := new(big.Int).Mul(big.NewInt(1e18), big.NewInt(5e5))
- input, err = abiObject.Pack("delegate", addr)
+ input, err = GovernanceABI.ABI.Pack("delegate", addr)
g.Require().NoError(err)
- _, err = g.call(addrDelegator, input, amount)
+ _, err = g.call(GovernanceContractAddress, addrDelegator, input, amount)
g.Require().NoError(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)
@@ -479,9 +523,9 @@ func (g *GovernanceContractTestSuite) TestFine() {
g.Require().Equal(1, len(g.s.QualifiedNodes()))
// Paying to node without fine should fail.
- input, err = abiObject.Pack("payFine", addr)
+ input, err = GovernanceABI.ABI.Pack("payFine", addr)
g.Require().NoError(err)
- _, err = g.call(addrDelegator, input, amount)
+ _, err = g.call(GovernanceContractAddress, addrDelegator, input, amount)
g.Require().NotNil(err)
// Fined.
@@ -497,50 +541,50 @@ func (g *GovernanceContractTestSuite) TestFine() {
g.Require().Equal(0, len(g.s.QualifiedNodes()))
// Cannot undelegate before fines are paied.
- input, err = abiObject.Pack("undelegate", addr)
+ input, err = GovernanceABI.ABI.Pack("undelegate", addr)
g.Require().NoError(err)
- _, err = g.call(addrDelegator, input, big.NewInt(0))
+ _, err = g.call(GovernanceContractAddress, addrDelegator, input, big.NewInt(0))
g.Require().NotNil(err)
// Only delegators can pay fine.
_, addrDelegator2 := g.newPrefundAccount()
- input, err = abiObject.Pack("payFine", addr)
+ input, err = GovernanceABI.ABI.Pack("payFine", addr)
g.Require().NoError(err)
- _, err = g.call(addrDelegator2, input, big.NewInt(5e5))
+ _, err = g.call(GovernanceContractAddress, addrDelegator2, input, big.NewInt(5e5))
g.Require().NotNil(err)
// Paying more than fine should fail.
payAmount := new(big.Int).Add(amount, amount)
- input, err = abiObject.Pack("payFine", addr)
+ input, err = GovernanceABI.ABI.Pack("payFine", addr)
g.Require().NoError(err)
- _, err = g.call(addrDelegator, input, payAmount)
+ _, err = g.call(GovernanceContractAddress, addrDelegator, input, payAmount)
g.Require().NotNil(err)
// Pay the fine.
- input, err = abiObject.Pack("payFine", addr)
+ input, err = GovernanceABI.ABI.Pack("payFine", addr)
g.Require().NoError(err)
- _, err = g.call(addrDelegator, input, amount)
+ _, err = g.call(GovernanceContractAddress, addrDelegator, input, amount)
g.Require().NoError(err)
// Qualified.
g.Require().Equal(1, len(g.s.QualifiedNodes()))
// Can undelegate after all fines are paied.
- input, err = abiObject.Pack("undelegate", addr)
+ input, err = GovernanceABI.ABI.Pack("undelegate", addr)
g.Require().NoError(err)
- _, err = g.call(addrDelegator, input, big.NewInt(0))
+ _, err = g.call(GovernanceContractAddress, addrDelegator, input, big.NewInt(0))
g.Require().NoError(err)
}
-func (g *GovernanceContractTestSuite) TestUnstakeWithExtraDelegators() {
+func (g *OracleContractsTestSuite) TestUnstakeWithExtraDelegators() {
privKey, addr := g.newPrefundAccount()
pk := crypto.FromECDSAPub(&privKey.PublicKey)
// Stake.
amount := new(big.Int).Mul(big.NewInt(1e18), big.NewInt(5e5))
- input, err := abiObject.Pack("stake", pk, "Test1", "test1@dexon.org", "Taipei, Taiwan", "https://dexon.org")
+ input, err := GovernanceABI.ABI.Pack("stake", pk, "Test1", "test1@dexon.org", "Taipei, Taiwan", "https://dexon.org")
g.Require().NoError(err)
- _, err = g.call(addr, input, amount)
+ _, err = g.call(GovernanceContractAddress, addr, input, amount)
g.Require().NoError(err)
// 1st delegator delegate to 1st node.
@@ -548,10 +592,10 @@ func (g *GovernanceContractTestSuite) TestUnstakeWithExtraDelegators() {
balanceBeforeDelegate := g.stateDB.GetBalance(addrDelegator)
amount = new(big.Int).Mul(big.NewInt(1e18), big.NewInt(3e5))
- input, err = abiObject.Pack("delegate", addr)
+ input, err = GovernanceABI.ABI.Pack("delegate", addr)
g.Require().NoError(err)
- _, err = g.call(addrDelegator, input, amount)
+ _, err = g.call(GovernanceContractAddress, addrDelegator, input, amount)
g.Require().NoError(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)
@@ -561,10 +605,10 @@ func (g *GovernanceContractTestSuite) TestUnstakeWithExtraDelegators() {
_, addrDelegator2 := g.newPrefundAccount()
balanceBeforeDelegate = g.stateDB.GetBalance(addrDelegator2)
- input, err = abiObject.Pack("delegate", addr)
+ input, err = GovernanceABI.ABI.Pack("delegate", addr)
g.Require().NoError(err)
- _, err = g.call(addrDelegator2, input, amount)
+ _, err = g.call(GovernanceContractAddress, addrDelegator2, input, amount)
g.Require().NoError(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)
@@ -573,19 +617,19 @@ func (g *GovernanceContractTestSuite) TestUnstakeWithExtraDelegators() {
g.Require().Equal(1, len(g.s.QualifiedNodes()))
// Unstake.
- input, err = abiObject.Pack("unstake")
+ input, err = GovernanceABI.ABI.Pack("unstake")
g.Require().NoError(err)
- _, err = g.call(addr, input, big.NewInt(0))
+ _, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0))
g.Require().NoError(err)
time.Sleep(time.Second * 2)
- input, err = abiObject.Pack("withdraw", addr)
+ input, err = GovernanceABI.ABI.Pack("withdraw", addr)
g.Require().NoError(err)
- _, err = g.call(addr, input, big.NewInt(0))
+ _, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0))
g.Require().NoError(err)
- _, err = g.call(addrDelegator, input, big.NewInt(0))
+ _, err = g.call(GovernanceContractAddress, addrDelegator, input, big.NewInt(0))
g.Require().NoError(err)
- _, err = g.call(addrDelegator2, input, big.NewInt(0))
+ _, err = g.call(GovernanceContractAddress, addrDelegator2, input, big.NewInt(0))
g.Require().NoError(err)
g.Require().Equal(0, int(g.s.LenDelegators(addr).Uint64()))
@@ -598,10 +642,10 @@ func (g *GovernanceContractTestSuite) TestUnstakeWithExtraDelegators() {
g.Require().Equal(big.NewInt(1), g.stateDB.GetBalance(GovernanceContractAddress))
}
-func (g *GovernanceContractTestSuite) TestUpdateConfiguration() {
+func (g *OracleContractsTestSuite) TestUpdateConfiguration() {
_, addr := g.newPrefundAccount()
- input, err := abiObject.Pack("updateConfiguration",
+ input, err := GovernanceABI.ABI.Pack("updateConfiguration",
new(big.Int).Mul(big.NewInt(1e18), big.NewInt(1e6)),
big.NewInt(1000),
big.NewInt(0.1875*decimalMultiplier),
@@ -621,196 +665,156 @@ func (g *GovernanceContractTestSuite) TestUpdateConfiguration() {
g.Require().NoError(err)
// Call with non-owner.
- _, err = g.call(addr, input, big.NewInt(0))
+ _, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0))
g.Require().NotNil(err)
// Call with owner.
- _, err = g.call(g.config.Owner, input, big.NewInt(0))
+ _, err = g.call(GovernanceContractAddress, g.config.Owner, input, big.NewInt(0))
g.Require().NoError(err)
}
-func (g *GovernanceContractTestSuite) TestSnapshotRound() {
- _, addr := g.newPrefundAccount()
-
- // Wrong height.
- input, err := abiObject.Pack("snapshotRound", big.NewInt(1), big.NewInt(666))
- g.Require().NoError(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().NoError(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().NoError(err)
- _, err = g.call(addr, input, big.NewInt(0))
- g.Require().NoError(err)
-
- // Duplicate round.
- input, err = abiObject.Pack("snapshotRound", big.NewInt(1), big.NewInt(1000))
- g.Require().NoError(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().NoError(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().NoError(err)
- _, err = g.call(addr, input, big.NewInt(0))
- g.Require().NoError(err)
-}
-
-func (g *GovernanceContractTestSuite) TestConfigurationReading() {
+func (g *OracleContractsTestSuite) TestConfigurationReading() {
_, addr := g.newPrefundAccount()
// CRS.
- input, err := abiObject.Pack("crs", big.NewInt(0))
+ input, err := GovernanceABI.ABI.Pack("crs", big.NewInt(0))
g.Require().NoError(err)
- res, err := g.call(addr, input, big.NewInt(0))
+ res, err := g.call(GovernanceContractAddress, addr, input, big.NewInt(0))
g.Require().NoError(err)
var crs0 [32]byte
- err = abiObject.Unpack(&crs0, "crs", res)
+ err = GovernanceABI.ABI.Unpack(&crs0, "crs", res)
g.Require().NoError(err)
g.Require().Equal(crypto.Keccak256Hash([]byte(g.config.GenesisCRSText)), common.BytesToHash(crs0[:]))
// Owner.
- input, err = abiObject.Pack("owner")
+ input, err = GovernanceABI.ABI.Pack("owner")
g.Require().NoError(err)
- res, err = g.call(addr, input, big.NewInt(0))
+ res, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0))
g.Require().NoError(err)
var owner common.Address
- err = abiObject.Unpack(&owner, "owner", res)
+ err = GovernanceABI.ABI.Unpack(&owner, "owner", res)
g.Require().NoError(err)
g.Require().Equal(g.config.Owner, owner)
// MinStake.
- input, err = abiObject.Pack("minStake")
+ input, err = GovernanceABI.ABI.Pack("minStake")
g.Require().NoError(err)
- res, err = g.call(addr, input, big.NewInt(0))
+ res, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0))
g.Require().NoError(err)
var value *big.Int
- err = abiObject.Unpack(&value, "minStake", res)
+ err = GovernanceABI.ABI.Unpack(&value, "minStake", res)
g.Require().NoError(err)
g.Require().Equal(g.config.MinStake.String(), value.String())
// BlockReward.
- input, err = abiObject.Pack("miningVelocity")
+ input, err = GovernanceABI.ABI.Pack("miningVelocity")
g.Require().NoError(err)
- res, err = g.call(addr, input, big.NewInt(0))
+ res, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0))
g.Require().NoError(err)
- err = abiObject.Unpack(&value, "miningVelocity", res)
+ err = GovernanceABI.ABI.Unpack(&value, "miningVelocity", res)
g.Require().NoError(err)
g.Require().Equal(g.config.MiningVelocity, float32(value.Uint64())/decimalMultiplier)
// BlockGasLimit.
- input, err = abiObject.Pack("blockGasLimit")
+ input, err = GovernanceABI.ABI.Pack("blockGasLimit")
g.Require().NoError(err)
- res, err = g.call(addr, input, big.NewInt(0))
+ res, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0))
g.Require().NoError(err)
- err = abiObject.Unpack(&value, "blockGasLimit", res)
+ err = GovernanceABI.ABI.Unpack(&value, "blockGasLimit", res)
g.Require().NoError(err)
g.Require().Equal(g.config.BlockGasLimit, value.Uint64())
// NumChains.
- input, err = abiObject.Pack("numChains")
+ input, err = GovernanceABI.ABI.Pack("numChains")
g.Require().NoError(err)
- res, err = g.call(addr, input, big.NewInt(0))
+ res, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0))
g.Require().NoError(err)
- err = abiObject.Unpack(&value, "numChains", res)
+ err = GovernanceABI.ABI.Unpack(&value, "numChains", res)
g.Require().NoError(err)
g.Require().Equal(g.config.NumChains, uint32(value.Uint64()))
// LambdaBA.
- input, err = abiObject.Pack("lambdaBA")
+ input, err = GovernanceABI.ABI.Pack("lambdaBA")
g.Require().NoError(err)
- res, err = g.call(addr, input, big.NewInt(0))
+ res, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0))
g.Require().NoError(err)
- err = abiObject.Unpack(&value, "lambdaBA", res)
+ err = GovernanceABI.ABI.Unpack(&value, "lambdaBA", res)
g.Require().NoError(err)
g.Require().Equal(g.config.LambdaBA, value.Uint64())
// LambdaDKG.
- input, err = abiObject.Pack("lambdaDKG")
+ input, err = GovernanceABI.ABI.Pack("lambdaDKG")
g.Require().NoError(err)
- res, err = g.call(addr, input, big.NewInt(0))
+ res, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0))
g.Require().NoError(err)
- err = abiObject.Unpack(&value, "lambdaDKG", res)
+ err = GovernanceABI.ABI.Unpack(&value, "lambdaDKG", res)
g.Require().NoError(err)
g.Require().Equal(g.config.LambdaDKG, value.Uint64())
// K.
- input, err = abiObject.Pack("k")
+ input, err = GovernanceABI.ABI.Pack("k")
g.Require().NoError(err)
- res, err = g.call(addr, input, big.NewInt(0))
+ res, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0))
g.Require().NoError(err)
- err = abiObject.Unpack(&value, "k", res)
+ err = GovernanceABI.ABI.Unpack(&value, "k", res)
g.Require().NoError(err)
g.Require().Equal(g.config.K, uint32(value.Uint64()))
// PhiRatio.
- input, err = abiObject.Pack("phiRatio")
+ input, err = GovernanceABI.ABI.Pack("phiRatio")
g.Require().NoError(err)
- res, err = g.call(addr, input, big.NewInt(0))
+ res, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0))
g.Require().NoError(err)
- err = abiObject.Unpack(&value, "phiRatio", res)
+ err = GovernanceABI.ABI.Unpack(&value, "phiRatio", res)
g.Require().NoError(err)
g.Require().Equal(g.config.PhiRatio, float32(value.Uint64())/decimalMultiplier)
// NotarySetSize.
- input, err = abiObject.Pack("notarySetSize")
+ input, err = GovernanceABI.ABI.Pack("notarySetSize")
g.Require().NoError(err)
- res, err = g.call(addr, input, big.NewInt(0))
+ res, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0))
g.Require().NoError(err)
- err = abiObject.Unpack(&value, "notarySetSize", res)
+ err = GovernanceABI.ABI.Unpack(&value, "notarySetSize", res)
g.Require().NoError(err)
g.Require().Equal(g.config.NotarySetSize, uint32(value.Uint64()))
// DKGSetSize.
- input, err = abiObject.Pack("dkgSetSize")
+ input, err = GovernanceABI.ABI.Pack("dkgSetSize")
g.Require().NoError(err)
- res, err = g.call(addr, input, big.NewInt(0))
+ res, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0))
g.Require().NoError(err)
- err = abiObject.Unpack(&value, "dkgSetSize", res)
+ err = GovernanceABI.ABI.Unpack(&value, "dkgSetSize", res)
g.Require().NoError(err)
g.Require().Equal(g.config.DKGSetSize, uint32(value.Uint64()))
// RoundInterval.
- input, err = abiObject.Pack("roundInterval")
+ input, err = GovernanceABI.ABI.Pack("roundInterval")
g.Require().NoError(err)
- res, err = g.call(addr, input, big.NewInt(0))
+ res, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0))
g.Require().NoError(err)
- err = abiObject.Unpack(&value, "roundInterval", res)
+ err = GovernanceABI.ABI.Unpack(&value, "roundInterval", res)
g.Require().NoError(err)
g.Require().Equal(g.config.RoundInterval, value.Uint64())
// MinBlockInterval.
- input, err = abiObject.Pack("minBlockInterval")
+ input, err = GovernanceABI.ABI.Pack("minBlockInterval")
g.Require().NoError(err)
- res, err = g.call(addr, input, big.NewInt(0))
+ res, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0))
g.Require().NoError(err)
- err = abiObject.Unpack(&value, "minBlockInterval", res)
+ err = GovernanceABI.ABI.Unpack(&value, "minBlockInterval", res)
g.Require().NoError(err)
g.Require().Equal(g.config.MinBlockInterval, value.Uint64())
}
-func (g *GovernanceContractTestSuite) TestReportForkVote() {
+func (g *OracleContractsTestSuite) TestReportForkVote() {
key, addr := g.newPrefundAccount()
pkBytes := crypto.FromECDSAPub(&key.PublicKey)
// Stake.
amount := new(big.Int).Mul(big.NewInt(1e18), big.NewInt(5e5))
- input, err := abiObject.Pack("stake", pkBytes, "Test1", "test1@dexon.org", "Taipei, Taiwan", "https://dexon.org")
+ input, err := GovernanceABI.ABI.Pack("stake", pkBytes, "Test1", "test1@dexon.org", "Taipei, Taiwan", "https://dexon.org")
g.Require().NoError(err)
- _, err = g.call(addr, input, amount)
+ _, err = g.call(GovernanceContractAddress, addr, input, amount)
g.Require().NoError(err)
pubKey := coreEcdsa.NewPublicKeyFromECDSA(&key.PublicKey)
@@ -833,23 +837,23 @@ func (g *GovernanceContractTestSuite) TestReportForkVote() {
g.Require().NoError(err)
// Report wrong type (fork block)
- input, err = abiObject.Pack("report", big.NewInt(2), vote1Bytes, vote2Bytes)
+ input, err = GovernanceABI.ABI.Pack("report", big.NewInt(2), vote1Bytes, vote2Bytes)
g.Require().NoError(err)
- _, err = g.call(addr, input, big.NewInt(0))
+ _, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0))
g.Require().Error(err)
- input, err = abiObject.Pack("report", big.NewInt(1), vote1Bytes, vote2Bytes)
+ input, err = GovernanceABI.ABI.Pack("report", big.NewInt(1), vote1Bytes, vote2Bytes)
g.Require().NoError(err)
- _, err = g.call(addr, input, big.NewInt(0))
+ _, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0))
g.Require().NoError(err)
node := g.s.Node(big.NewInt(0))
g.Require().Equal(node.Fined, g.s.FineValue(big.NewInt(1)))
// Duplicate report should fail.
- input, err = abiObject.Pack("report", big.NewInt(1), vote1Bytes, vote2Bytes)
+ input, err = GovernanceABI.ABI.Pack("report", big.NewInt(1), vote1Bytes, vote2Bytes)
g.Require().NoError(err)
- _, err = g.call(addr, input, big.NewInt(0))
+ _, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0))
g.Require().Error(err)
// Check if finedRecords is set.
@@ -857,26 +861,26 @@ func (g *GovernanceContractTestSuite) TestReportForkVote() {
sort.Sort(sortBytes(payloads))
hash := Bytes32(crypto.Keccak256Hash(payloads...))
- input, err = abiObject.Pack("finedRecords", hash)
+ input, err = GovernanceABI.ABI.Pack("finedRecords", hash)
g.Require().NoError(err)
- res, err := g.call(addr, input, big.NewInt(0))
+ res, err := g.call(GovernanceContractAddress, addr, input, big.NewInt(0))
g.Require().NoError(err)
var value bool
- err = abiObject.Unpack(&value, "finedRecords", res)
+ err = GovernanceABI.ABI.Unpack(&value, "finedRecords", res)
g.Require().NoError(err)
g.Require().True(value)
}
-func (g *GovernanceContractTestSuite) TestReportForkBlock() {
+func (g *OracleContractsTestSuite) TestReportForkBlock() {
key, addr := g.newPrefundAccount()
pkBytes := crypto.FromECDSAPub(&key.PublicKey)
// Stake.
amount := new(big.Int).Mul(big.NewInt(1e18), big.NewInt(5e5))
- input, err := abiObject.Pack("stake", pkBytes, "Test1", "test1@dexon.org", "Taipei, Taiwan", "https://dexon.org")
+ input, err := GovernanceABI.ABI.Pack("stake", pkBytes, "Test1", "test1@dexon.org", "Taipei, Taiwan", "https://dexon.org")
g.Require().NoError(err)
- _, err = g.call(addr, input, amount)
+ _, err = g.call(GovernanceContractAddress, addr, input, amount)
g.Require().NoError(err)
privKey := coreEcdsa.NewPrivateKeyFromECDSA(key)
@@ -910,23 +914,23 @@ func (g *GovernanceContractTestSuite) TestReportForkBlock() {
g.Require().NoError(err)
// Report wrong type (fork vote)
- input, err = abiObject.Pack("report", big.NewInt(1), block1Bytes, block2Bytes)
+ input, err = GovernanceABI.ABI.Pack("report", big.NewInt(1), block1Bytes, block2Bytes)
g.Require().NoError(err)
- _, err = g.call(addr, input, big.NewInt(0))
+ _, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0))
g.Require().Error(err)
- input, err = abiObject.Pack("report", big.NewInt(2), block1Bytes, block2Bytes)
+ input, err = GovernanceABI.ABI.Pack("report", big.NewInt(2), block1Bytes, block2Bytes)
g.Require().NoError(err)
- _, err = g.call(addr, input, big.NewInt(0))
+ _, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0))
g.Require().NoError(err)
node := g.s.Node(big.NewInt(0))
g.Require().Equal(node.Fined, g.s.FineValue(big.NewInt(2)))
// Duplicate report should fail.
- input, err = abiObject.Pack("report", big.NewInt(2), block1Bytes, block2Bytes)
+ input, err = GovernanceABI.ABI.Pack("report", big.NewInt(2), block1Bytes, block2Bytes)
g.Require().NoError(err)
- _, err = g.call(addr, input, big.NewInt(0))
+ _, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0))
g.Require().Error(err)
// Check if finedRecords is set.
@@ -934,113 +938,113 @@ func (g *GovernanceContractTestSuite) TestReportForkBlock() {
sort.Sort(sortBytes(payloads))
hash := Bytes32(crypto.Keccak256Hash(payloads...))
- input, err = abiObject.Pack("finedRecords", hash)
+ input, err = GovernanceABI.ABI.Pack("finedRecords", hash)
g.Require().NoError(err)
- res, err := g.call(addr, input, big.NewInt(0))
+ res, err := g.call(GovernanceContractAddress, addr, input, big.NewInt(0))
g.Require().NoError(err)
var value bool
- err = abiObject.Unpack(&value, "finedRecords", res)
+ err = GovernanceABI.ABI.Unpack(&value, "finedRecords", res)
g.Require().NoError(err)
g.Require().True(value)
}
-func (g *GovernanceContractTestSuite) TestMiscVariableReading() {
+func (g *OracleContractsTestSuite) TestMiscVariableReading() {
privKey, addr := g.newPrefundAccount()
pk := crypto.FromECDSAPub(&privKey.PublicKey)
- input, err := abiObject.Pack("totalSupply")
+ input, err := GovernanceABI.ABI.Pack("totalSupply")
g.Require().NoError(err)
- res, err := g.call(addr, input, big.NewInt(0))
+ res, err := g.call(GovernanceContractAddress, addr, input, big.NewInt(0))
g.Require().NoError(err)
- input, err = abiObject.Pack("totalStaked")
+ input, err = GovernanceABI.ABI.Pack("totalStaked")
g.Require().NoError(err)
- res, err = g.call(addr, input, big.NewInt(0))
+ res, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0))
g.Require().NoError(err)
// Stake.
amount := new(big.Int).Mul(big.NewInt(1e18), big.NewInt(5e5))
- input, err = abiObject.Pack("stake", pk, "Test1", "test1@dexon.org", "Taipei, Taiwan", "https://dexon.org")
+ input, err = GovernanceABI.ABI.Pack("stake", pk, "Test1", "test1@dexon.org", "Taipei, Taiwan", "https://dexon.org")
g.Require().NoError(err)
- _, err = g.call(addr, input, amount)
+ _, err = g.call(GovernanceContractAddress, addr, input, amount)
g.Require().NoError(err)
// 1st delegator delegate to 1st node.
_, addrDelegator := g.newPrefundAccount()
amount = new(big.Int).Mul(big.NewInt(1e18), big.NewInt(3e5))
- input, err = abiObject.Pack("delegate", addr)
+ input, err = GovernanceABI.ABI.Pack("delegate", addr)
g.Require().NoError(err)
- _, err = g.call(addrDelegator, input, amount)
+ _, err = g.call(GovernanceContractAddress, addrDelegator, input, amount)
g.Require().NoError(err)
// 2st delegator delegate to 1st node.
_, addrDelegator2 := g.newPrefundAccount()
- input, err = abiObject.Pack("delegate", addr)
+ input, err = GovernanceABI.ABI.Pack("delegate", addr)
g.Require().NoError(err)
- _, err = g.call(addrDelegator2, input, amount)
+ _, err = g.call(GovernanceContractAddress, addrDelegator2, input, amount)
g.Require().NoError(err)
- input, err = abiObject.Pack("nodes", big.NewInt(0))
+ input, err = GovernanceABI.ABI.Pack("nodes", big.NewInt(0))
g.Require().NoError(err)
- res, err = g.call(addr, input, big.NewInt(0))
+ res, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0))
g.Require().NoError(err)
- input, err = abiObject.Pack("nodesLength")
+ input, err = GovernanceABI.ABI.Pack("nodesLength")
g.Require().NoError(err)
- res, err = g.call(addr, input, big.NewInt(0))
+ res, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0))
g.Require().NoError(err)
var value *big.Int
- err = abiObject.Unpack(&value, "nodesLength", res)
+ err = GovernanceABI.ABI.Unpack(&value, "nodesLength", res)
g.Require().NoError(err)
g.Require().Equal(1, int(value.Uint64()))
- input, err = abiObject.Pack("nodesOffsetByAddress", addr)
+ input, err = GovernanceABI.ABI.Pack("nodesOffsetByAddress", addr)
g.Require().NoError(err)
- res, err = g.call(addr, input, big.NewInt(0))
+ res, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0))
g.Require().NoError(err)
- err = abiObject.Unpack(&value, "nodesOffsetByAddress", res)
+ err = GovernanceABI.ABI.Unpack(&value, "nodesOffsetByAddress", res)
g.Require().NoError(err)
g.Require().Equal(0, int(value.Uint64()))
id, err := publicKeyToNodeID(pk)
g.Require().NoError(err)
- input, err = abiObject.Pack("nodesOffsetByID", id)
+ input, err = GovernanceABI.ABI.Pack("nodesOffsetByID", id)
g.Require().NoError(err)
- res, err = g.call(addr, input, big.NewInt(0))
+ res, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0))
g.Require().NoError(err)
- err = abiObject.Unpack(&value, "nodesOffsetByID", res)
+ err = GovernanceABI.ABI.Unpack(&value, "nodesOffsetByID", res)
g.Require().NoError(err)
g.Require().Equal(0, int(value.Uint64()))
- input, err = abiObject.Pack("delegators", addr, big.NewInt(0))
+ input, err = GovernanceABI.ABI.Pack("delegators", addr, big.NewInt(0))
g.Require().NoError(err)
- res, err = g.call(addr, input, big.NewInt(0))
+ res, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0))
g.Require().NoError(err)
- input, err = abiObject.Pack("delegatorsLength", addr)
+ input, err = GovernanceABI.ABI.Pack("delegatorsLength", addr)
g.Require().NoError(err)
- res, err = g.call(addr, input, big.NewInt(0))
+ res, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0))
g.Require().NoError(err)
- err = abiObject.Unpack(&value, "delegatorsLength", res)
+ err = GovernanceABI.ABI.Unpack(&value, "delegatorsLength", res)
g.Require().NoError(err)
g.Require().Equal(3, int(value.Uint64()))
- input, err = abiObject.Pack("delegatorsOffset", addr, addrDelegator2)
+ input, err = GovernanceABI.ABI.Pack("delegatorsOffset", addr, addrDelegator2)
g.Require().NoError(err)
- res, err = g.call(addr, input, big.NewInt(0))
+ res, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0))
g.Require().NoError(err)
- err = abiObject.Unpack(&value, "delegatorsOffset", res)
+ err = GovernanceABI.ABI.Unpack(&value, "delegatorsOffset", res)
g.Require().NoError(err)
g.Require().Equal(2, int(value.Uint64()))
- input, err = abiObject.Pack("fineValues", big.NewInt(0))
+ input, err = GovernanceABI.ABI.Pack("fineValues", big.NewInt(0))
g.Require().NoError(err)
- res, err = g.call(addr, input, big.NewInt(0))
+ res, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0))
g.Require().NoError(err)
}
-func (g *GovernanceContractTestSuite) TestHalvingCondition() {
+func (g *OracleContractsTestSuite) TestHalvingCondition() {
// TotalSupply 2.5B reached
g.s.MiningHalved()
g.Require().Equal(new(big.Int).Mul(big.NewInt(1e18), big.NewInt(3.25e9)).String(),
@@ -1056,6 +1060,202 @@ func (g *GovernanceContractTestSuite) TestHalvingCondition() {
g.s.LastHalvedAmount().String())
}
+func (g *OracleContractsTestSuite) TestNodeInfoOracleContract() {
+ privKey, addr := g.newPrefundAccount()
+ pk := crypto.FromECDSAPub(&privKey.PublicKey)
+
+ // Stake.
+ amount := new(big.Int).Mul(big.NewInt(1e18), big.NewInt(5e5))
+ input, err := GovernanceABI.ABI.Pack("stake", pk, "Test1", "test1@dexon.org", "Taipei, Taiwan", "https://dexon.org")
+ g.Require().NoError(err)
+ _, err = g.call(GovernanceContractAddress, addr, input, amount)
+ g.Require().NoError(err)
+
+ // Invalid round.
+ input, err = NodeInfoOracleABI.ABI.Pack("delegators", big.NewInt(100), addr, big.NewInt(0))
+ g.Require().NoError(err)
+ res, err := g.call(NodeInfoOracleAddress, addr, input, big.NewInt(0))
+ g.Require().Error(err)
+
+ round := big.NewInt(0)
+ input, err = NodeInfoOracleABI.ABI.Pack("delegators", round, addr, big.NewInt(0))
+ g.Require().NoError(err)
+ res, err = g.call(NodeInfoOracleAddress, addr, input, big.NewInt(0))
+ g.Require().NoError(err)
+
+ var value *big.Int
+ input, err = NodeInfoOracleABI.ABI.Pack("delegatorsLength", round, addr)
+ g.Require().NoError(err)
+ res, err = g.call(NodeInfoOracleAddress, addr, input, big.NewInt(0))
+ g.Require().NoError(err)
+ err = NodeInfoOracleABI.ABI.Unpack(&value, "delegatorsLength", res)
+ g.Require().NoError(err)
+ g.Require().Equal(1, int(value.Uint64()))
+
+ input, err = NodeInfoOracleABI.ABI.Pack("delegatorsOffset", round, addr, addr)
+ g.Require().NoError(err)
+ res, err = g.call(NodeInfoOracleAddress, addr, input, big.NewInt(0))
+ g.Require().NoError(err)
+ err = NodeInfoOracleABI.ABI.Unpack(&value, "delegatorsOffset", res)
+ g.Require().NoError(err)
+ g.Require().Equal(0, int(value.Uint64()))
+}
+
+type testCoreMock struct {
+ newDKGGPKError error
+ tsigReturn bool
+}
+
+func (m *testCoreMock) SetState(GovernanceStateHelper) {}
+
+func (m *testCoreMock) NewGroupPublicKey(*big.Int, int) (tsigVerifierIntf, error) {
+ if m.newDKGGPKError != nil {
+ return nil, m.newDKGGPKError
+ }
+ return &testTSigVerifierMock{m.tsigReturn}, nil
+}
+
+type testTSigVerifierMock struct {
+ ret bool
+}
+
+func (v *testTSigVerifierMock) VerifySignature(coreCommon.Hash, coreCrypto.Signature) bool {
+ return v.ret
+}
+
+func (g *OracleContractsTestSuite) TestResetDKG() {
+ for i := uint32(0); i < g.config.DKGSetSize; i++ {
+ privKey, addr := g.newPrefundAccount()
+ pk := crypto.FromECDSAPub(&privKey.PublicKey)
+
+ // Stake.
+ amount := new(big.Int).Mul(big.NewInt(1e18), big.NewInt(1e6))
+ input, err := GovernanceABI.ABI.Pack("stake", pk, "Test1", "test1@dexon.org", "Taipei, Taiwan", "https://dexon.org")
+ g.Require().NoError(err)
+ _, err = g.call(GovernanceContractAddress, addr, input, amount)
+ g.Require().NoError(err)
+ }
+ g.Require().Len(g.s.QualifiedNodes(), int(g.config.DKGSetSize))
+
+ addrs := make(map[int][]common.Address)
+ addDKG := func(round int, final bool) {
+ addrs[round] = []common.Address{}
+ r := big.NewInt(int64(round))
+ target := coreTypes.NewDKGSetTarget(coreCommon.Hash(g.s.CRS(r)))
+ ns := coreTypes.NewNodeSet()
+
+ for _, x := range g.s.QualifiedNodes() {
+ mpk, err := coreEcdsa.NewPublicKeyFromByteSlice(x.PublicKey)
+ if err != nil {
+ panic(err)
+ }
+ ns.Add(coreTypes.NewNodeID(mpk))
+ }
+ dkgSet := ns.GetSubSet(int(g.s.DKGSetSize().Uint64()), target)
+ g.Require().Len(dkgSet, int(g.config.DKGSetSize))
+
+ for id := range dkgSet {
+ offset := g.s.NodesOffsetByID(Bytes32(id.Hash))
+ if offset.Cmp(big.NewInt(0)) < 0 {
+ panic("DKG node does not exist")
+ }
+ node := g.s.Node(offset)
+ // Prepare MPK.
+ g.s.PushDKGMasterPublicKey(r, randomBytes(32, 64))
+ // Prepare Complaint.
+ g.s.PushDKGComplaint(r, randomBytes(32, 64))
+ addr := node.Owner
+ addrs[round] = append(addrs[round], addr)
+ // Prepare MPK Ready.
+ g.s.PutDKGMPKReady(r, addr, true)
+ g.s.IncDKGMPKReadysCount(r)
+ if final {
+ // Prepare Finalized.
+ g.s.PutDKGFinalized(r, addr, true)
+ g.s.IncDKGFinalizedsCount(r)
+ }
+ }
+ dkgSetSize := len(dkgSet)
+ g.Require().Len(g.s.DKGMasterPublicKeys(r), dkgSetSize)
+ g.Require().Len(g.s.DKGComplaints(r), dkgSetSize)
+ g.Require().Equal(0, g.s.DKGMPKReadysCount(r).Cmp(big.NewInt(int64(dkgSetSize))))
+ for _, addr := range addrs[round] {
+ g.Require().True(g.s.DKGMPKReady(r, addr))
+ }
+ if final {
+ g.Require().Equal(0, g.s.DKGFinalizedsCount(r).Cmp(big.NewInt(int64(dkgSetSize))))
+ for _, addr := range addrs[round] {
+ g.Require().True(g.s.DKGFinalized(r, addr))
+ }
+ }
+ }
+
+ // Fill data for previous rounds.
+ roundHeight := int64(g.config.RoundInterval / g.config.MinBlockInterval)
+ round := 3
+ for i := 0; i <= round; i++ {
+ // Prepare CRS.
+ crs := common.BytesToHash(randomBytes(common.HashLength, common.HashLength))
+ g.s.PushCRS(crs)
+ // Prepare Round Height
+ if i != 0 {
+ g.s.PushRoundHeight(big.NewInt(int64(i) * roundHeight))
+ }
+ g.Require().Equal(0, g.s.LenCRS().Cmp(big.NewInt(int64(i+2))))
+ g.Require().Equal(crs, g.s.CurrentCRS())
+ }
+ for i := 0; i <= round; i++ {
+ addDKG(i, true)
+ }
+
+ mock := &testCoreMock{
+ tsigReturn: true,
+ }
+ OracleContracts[GovernanceContractAddress].(*GovernanceContract).coreDKGUtils = mock
+ repeat := 3
+ for r := 0; r < repeat; r++ {
+ addDKG(round+1, false)
+ // Add one finalized for test.
+ roundPlusOne := big.NewInt(int64(round + 1))
+ g.s.PutDKGFinalized(roundPlusOne, addrs[round+1][0], true)
+ g.s.IncDKGFinalizedsCount(roundPlusOne)
+
+ g.context.BlockNumber = big.NewInt(roundHeight*int64(round) + roundHeight*int64(r) + roundHeight*80/100)
+ _, addr := g.newPrefundAccount()
+ newCRS := randomBytes(common.HashLength, common.HashLength)
+ input, err := GovernanceABI.ABI.Pack("resetDKG", newCRS)
+ g.Require().NoError(err)
+ _, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0))
+ g.Require().NoError(err)
+
+ // Test if CRS is reset.
+ newCRSHash := crypto.Keccak256Hash(newCRS)
+ g.Require().Equal(0, g.s.LenCRS().Cmp(big.NewInt(int64(round+2))))
+ g.Require().Equal(newCRSHash, g.s.CurrentCRS())
+ g.Require().Equal(newCRSHash, g.s.CRS(big.NewInt(int64(round+1))))
+
+ // Test if MPK is purged.
+ g.Require().Len(g.s.DKGMasterPublicKeys(big.NewInt(int64(round+1))), 0)
+ // Test if MPKReady is purged.
+ g.Require().Equal(0,
+ g.s.DKGMPKReadysCount(big.NewInt(int64(round+1))).Cmp(big.NewInt(0)))
+ for _, addr := range addrs[round+1] {
+ g.Require().False(g.s.DKGMPKReady(big.NewInt(int64(round+1)), addr))
+ }
+ // Test if Complaint is purged.
+ g.Require().Len(g.s.DKGComplaints(big.NewInt(int64(round+1))), 0)
+ // Test if Finalized is purged.
+ g.Require().Equal(0,
+ g.s.DKGFinalizedsCount(big.NewInt(int64(round+1))).Cmp(big.NewInt(0)))
+ for _, addr := range addrs[round+1] {
+ g.Require().False(g.s.DKGFinalized(big.NewInt(int64(round+1)), addr))
+ }
+
+ g.Require().Equal(0,
+ g.s.DKGResetCount(roundPlusOne).Cmp(big.NewInt(int64(r+1))))
+ }
+}
+
func TestGovernanceContract(t *testing.T) {
- suite.Run(t, new(GovernanceContractTestSuite))
+ suite.Run(t, new(OracleContractsTestSuite))
}