aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/vm/oracle_contract_abi.go840
-rw-r--r--core/vm/oracle_contracts.go182
-rw-r--r--core/vm/oracle_contracts_test.go191
-rw-r--r--dex/handler.go33
-rw-r--r--dex/handler_test.go77
-rw-r--r--dex/helper_test.go11
-rw-r--r--p2p/peer_error.go1
-rw-r--r--params/config.go70
-rw-r--r--params/gen_dexcon_config.go12
9 files changed, 1025 insertions, 392 deletions
diff --git a/core/vm/oracle_contract_abi.go b/core/vm/oracle_contract_abi.go
index 535161bd4..23ec7cd9d 100644
--- a/core/vm/oracle_contract_abi.go
+++ b/core/vm/oracle_contract_abi.go
@@ -56,6 +56,60 @@ const GovernanceABIJSON = `
"type": "function"
},
{
+ "constant": false,
+ "inputs": [
+ {
+ "name": "MinStake",
+ "type": "uint256"
+ },
+ {
+ "name": "LockupPeriod",
+ "type": "uint256"
+ },
+ {
+ "name": "MinGasPrice",
+ "type": "uint256"
+ },
+ {
+ "name": "BlockGasLimit",
+ "type": "uint256"
+ },
+ {
+ "name": "LambdaBA",
+ "type": "uint256"
+ },
+ {
+ "name": "LambdaDKG",
+ "type": "uint256"
+ },
+ {
+ "name": "NotaryParamAlpha",
+ "type": "uint256"
+ },
+ {
+ "name": "NotaryParamBeta",
+ "type": "uint256"
+ },
+ {
+ "name": "RoundLength",
+ "type": "uint256"
+ },
+ {
+ "name": "MinBlockInterval",
+ "type": "uint256"
+ },
+ {
+ "name": "FineValues",
+ "type": "uint256[]"
+ }
+ ],
+ "name": "updateConfiguration",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
"constant": true,
"inputs": [],
"name": "totalSupply",
@@ -70,6 +124,39 @@ const GovernanceABIJSON = `
"type": "function"
},
{
+ "constant": false,
+ "inputs": [
+ {
+ "name": "PublicKey",
+ "type": "bytes"
+ }
+ ],
+ "name": "addDKGMasterPublicKey",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "name": "addressWhitelist",
+ "outputs": [
+ {
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
"constant": true,
"inputs": [
{
@@ -139,6 +226,20 @@ const GovernanceABIJSON = `
"type": "function"
},
{
+ "constant": false,
+ "inputs": [
+ {
+ "name": "MPKReady",
+ "type": "bytes"
+ }
+ ],
+ "name": "addDKGMPKReady",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
"constant": true,
"inputs": [],
"name": "miningVelocity",
@@ -153,6 +254,20 @@ const GovernanceABIJSON = `
"type": "function"
},
{
+ "constant": false,
+ "inputs": [
+ {
+ "name": "Finalize",
+ "type": "bytes"
+ }
+ ],
+ "name": "addDKGFinalize",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
"constant": true,
"inputs": [],
"name": "lambdaBA",
@@ -167,6 +282,42 @@ const GovernanceABIJSON = `
"type": "function"
},
{
+ "constant": false,
+ "inputs": [
+ {
+ "name": "Amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "unstake",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "Type",
+ "type": "uint256"
+ },
+ {
+ "name": "Arg1",
+ "type": "bytes"
+ },
+ {
+ "name": "Arg2",
+ "type": "bytes"
+ }
+ ],
+ "name": "report",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
"constant": true,
"inputs": [],
"name": "minStake",
@@ -181,6 +332,66 @@ const GovernanceABIJSON = `
"type": "function"
},
{
+ "constant": false,
+ "inputs": [],
+ "name": "stake",
+ "outputs": [],
+ "payable": true,
+ "stateMutability": "payable",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [],
+ "name": "withdraw",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "NodeAddress",
+ "type": "address"
+ }
+ ],
+ "name": "payFine",
+ "outputs": [],
+ "payable": true,
+ "stateMutability": "payable",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "NewPublicKey",
+ "type": "bytes"
+ }
+ ],
+ "name": "replaceNodePublicKey",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "NewOwner",
+ "type": "address"
+ }
+ ],
+ "name": "transferNodeOwnership",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
"constant": true,
"inputs": [],
"name": "crsRound",
@@ -223,6 +434,48 @@ const GovernanceABIJSON = `
"type": "function"
},
{
+ "constant": false,
+ "inputs": [
+ {
+ "name": "Success",
+ "type": "bytes"
+ }
+ ],
+ "name": "addDKGSuccess",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "withdrawable",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "NewSignedCRS",
+ "type": "bytes"
+ }
+ ],
+ "name": "resetDKG",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
"constant": true,
"inputs": [
{
@@ -258,6 +511,20 @@ const GovernanceABIJSON = `
{
"constant": true,
"inputs": [],
+ "name": "whitelistLength",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
"name": "dkgRound",
"outputs": [
{
@@ -270,6 +537,24 @@ const GovernanceABIJSON = `
"type": "function"
},
{
+ "constant": false,
+ "inputs": [
+ {
+ "name": "OldOwner",
+ "type": "address"
+ },
+ {
+ "name": "NewOwner",
+ "type": "address"
+ }
+ ],
+ "name": "transferNodeOwnershipByFoundation",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
"constant": true,
"inputs": [],
"name": "totalStaked",
@@ -317,6 +602,25 @@ const GovernanceABIJSON = `
"type": "function"
},
{
+ "constant": false,
+ "inputs": [
+ {
+ "name": "addr",
+ "type": "address"
+ }
+ ],
+ "name": "removeFromWhitelist",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
"constant": true,
"inputs": [],
"name": "roundLength",
@@ -382,6 +686,25 @@ const GovernanceABIJSON = `
"inputs": [
{
"name": "",
+ "type": "address"
+ }
+ ],
+ "name": "whitelistOffsetByAddress",
+ "outputs": [
+ {
+ "name": "",
+ "type": "int256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [
+ {
+ "name": "",
"type": "bytes32"
}
],
@@ -463,6 +786,20 @@ const GovernanceABIJSON = `
"type": "function"
},
{
+ "constant": false,
+ "inputs": [
+ {
+ "name": "Complaint",
+ "type": "bytes"
+ }
+ ],
+ "name": "addDKGComplaint",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
"constant": true,
"inputs": [
{
@@ -529,6 +866,50 @@ const GovernanceABIJSON = `
"type": "function"
},
{
+ "constant": false,
+ "inputs": [
+ {
+ "name": "Round",
+ "type": "uint256"
+ },
+ {
+ "name": "SignedCRS",
+ "type": "bytes"
+ }
+ ],
+ "name": "proposeCRS",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "Name",
+ "type": "string"
+ },
+ {
+ "name": "Email",
+ "type": "string"
+ },
+ {
+ "name": "Location",
+ "type": "string"
+ },
+ {
+ "name": "Url",
+ "type": "string"
+ }
+ ],
+ "name": "updateNodeInfo",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
"constant": true,
"inputs": [
{
@@ -548,6 +929,36 @@ const GovernanceABIJSON = `
"type": "function"
},
{
+ "constant": false,
+ "inputs": [
+ {
+ "name": "PublicKey",
+ "type": "bytes"
+ },
+ {
+ "name": "Name",
+ "type": "string"
+ },
+ {
+ "name": "Email",
+ "type": "string"
+ },
+ {
+ "name": "Location",
+ "type": "string"
+ },
+ {
+ "name": "Url",
+ "type": "string"
+ }
+ ],
+ "name": "register",
+ "outputs": [],
+ "payable": true,
+ "stateMutability": "payable",
+ "type": "function"
+ },
+ {
"constant": true,
"inputs": [
{
@@ -595,6 +1006,25 @@ const GovernanceABIJSON = `
"type": "function"
},
{
+ "constant": false,
+ "inputs": [
+ {
+ "name": "addr",
+ "type": "address"
+ }
+ ],
+ "name": "addToWhitelist",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
"constant": true,
"inputs": [
{
@@ -666,6 +1096,48 @@ const GovernanceABIJSON = `
"type": "function"
},
{
+ "constant": false,
+ "inputs": [
+ {
+ "name": "NewOwner",
+ "type": "address"
+ }
+ ],
+ "name": "transferOwnership",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "nodesLength",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "isConsortium",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
"anonymous": false,
"inputs": [],
"name": "ConfigurationChanged",
@@ -874,374 +1346,6 @@ const GovernanceABIJSON = `
],
"name": "DKGReset",
"type": "event"
- },
- {
- "constant": false,
- "inputs": [
- {
- "name": "NewOwner",
- "type": "address"
- }
- ],
- "name": "transferOwnership",
- "outputs": [],
- "payable": false,
- "stateMutability": "nonpayable",
- "type": "function"
- },
- {
- "constant": false,
- "inputs": [
- {
- "name": "MinStake",
- "type": "uint256"
- },
- {
- "name": "LockupPeriod",
- "type": "uint256"
- },
- {
- "name": "MinGasPrice",
- "type": "uint256"
- },
- {
- "name": "BlockGasLimit",
- "type": "uint256"
- },
- {
- "name": "LambdaBA",
- "type": "uint256"
- },
- {
- "name": "LambdaDKG",
- "type": "uint256"
- },
- {
- "name": "NotaryParamAlpha",
- "type": "uint256"
- },
- {
- "name": "NotaryParamBeta",
- "type": "uint256"
- },
- {
- "name": "RoundLength",
- "type": "uint256"
- },
- {
- "name": "MinBlockInterval",
- "type": "uint256"
- },
- {
- "name": "FineValues",
- "type": "uint256[]"
- }
- ],
- "name": "updateConfiguration",
- "outputs": [],
- "payable": false,
- "stateMutability": "nonpayable",
- "type": "function"
- },
- {
- "constant": false,
- "inputs": [
- {
- "name": "Complaint",
- "type": "bytes"
- }
- ],
- "name": "addDKGComplaint",
- "outputs": [],
- "payable": false,
- "stateMutability": "nonpayable",
- "type": "function"
- },
- {
- "constant": false,
- "inputs": [
- {
- "name": "PublicKey",
- "type": "bytes"
- }
- ],
- "name": "addDKGMasterPublicKey",
- "outputs": [],
- "payable": false,
- "stateMutability": "nonpayable",
- "type": "function"
- },
- {
- "constant": false,
- "inputs": [
- {
- "name": "MPKReady",
- "type": "bytes"
- }
- ],
- "name": "addDKGMPKReady",
- "outputs": [],
- "payable": false,
- "stateMutability": "nonpayable",
- "type": "function"
- },
- {
- "constant": false,
- "inputs": [
- {
- "name": "Finalize",
- "type": "bytes"
- }
- ],
- "name": "addDKGFinalize",
- "outputs": [],
- "payable": false,
- "stateMutability": "nonpayable",
- "type": "function"
- },
- {
- "constant": false,
- "inputs": [
- {
- "name": "Success",
- "type": "bytes"
- }
- ],
- "name": "addDKGSuccess",
- "outputs": [],
- "payable": false,
- "stateMutability": "nonpayable",
- "type": "function"
- },
- {
- "constant": false,
- "inputs": [
- {
- "name": "NodeAddress",
- "type": "address"
- }
- ],
- "name": "payFine",
- "outputs": [],
- "payable": true,
- "stateMutability": "payable",
- "type": "function"
- },
- {
- "constant": true,
- "inputs": [],
- "name": "nodesLength",
- "outputs": [
- {
- "name": "",
- "type": "uint256"
- }
- ],
- "payable": false,
- "stateMutability": "view",
- "type": "function"
- },
- {
- "constant": false,
- "inputs": [
- {
- "name": "Round",
- "type": "uint256"
- },
- {
- "name": "SignedCRS",
- "type": "bytes"
- }
- ],
- "name": "proposeCRS",
- "outputs": [],
- "payable": false,
- "stateMutability": "nonpayable",
- "type": "function"
- },
- {
- "constant": false,
- "inputs": [
- {
- "name": "Type",
- "type": "uint256"
- },
- {
- "name": "Arg1",
- "type": "bytes"
- },
- {
- "name": "Arg2",
- "type": "bytes"
- }
- ],
- "name": "report",
- "outputs": [],
- "payable": false,
- "stateMutability": "nonpayable",
- "type": "function"
- },
- {
- "constant": false,
- "inputs": [
- {
- "name": "NewSignedCRS",
- "type": "bytes"
- }
- ],
- "name": "resetDKG",
- "outputs": [],
- "payable": false,
- "stateMutability": "nonpayable",
- "type": "function"
- },
- {
- "constant": false,
- "inputs": [
- {
- "name": "PublicKey",
- "type": "bytes"
- },
- {
- "name": "Name",
- "type": "string"
- },
- {
- "name": "Email",
- "type": "string"
- },
- {
- "name": "Location",
- "type": "string"
- },
- {
- "name": "Url",
- "type": "string"
- }
- ],
- "name": "register",
- "outputs": [],
- "payable": true,
- "stateMutability": "payable",
- "type": "function"
- },
- {
- "constant": false,
- "inputs": [
- {
- "name": "NewPublicKey",
- "type": "bytes"
- }
- ],
- "name": "replaceNodePublicKey",
- "outputs": [],
- "payable": false,
- "stateMutability": "nonpayable",
- "type": "function"
- },
- {
- "constant": false,
- "inputs": [],
- "name": "stake",
- "outputs": [],
- "payable": true,
- "stateMutability": "payable",
- "type": "function"
- },
- {
- "constant": false,
- "inputs": [
- {
- "name": "NewOwner",
- "type": "address"
- }
- ],
- "name": "transferNodeOwnership",
- "outputs": [],
- "payable": false,
- "stateMutability": "nonpayable",
- "type": "function"
- },
- {
- "constant": false,
- "inputs": [
- {
- "name": "OldOwner",
- "type": "address"
- },
- {
- "name": "NewOwner",
- "type": "address"
- }
- ],
- "name": "transferNodeOwnershipByFoundation",
- "outputs": [],
- "payable": false,
- "stateMutability": "nonpayable",
- "type": "function"
- },
- {
- "constant": false,
- "inputs": [
- {
- "name": "Amount",
- "type": "uint256"
- }
- ],
- "name": "unstake",
- "outputs": [],
- "payable": false,
- "stateMutability": "nonpayable",
- "type": "function"
- },
- {
- "constant": false,
- "inputs": [
- {
- "name": "Name",
- "type": "string"
- },
- {
- "name": "Email",
- "type": "string"
- },
- {
- "name": "Location",
- "type": "string"
- },
- {
- "name": "Url",
- "type": "string"
- }
- ],
- "name": "updateNodeInfo",
- "outputs": [],
- "payable": false,
- "stateMutability": "nonpayable",
- "type": "function"
- },
- {
- "constant": false,
- "inputs": [],
- "name": "withdraw",
- "outputs": [],
- "payable": false,
- "stateMutability": "nonpayable",
- "type": "function"
- },
- {
- "constant": true,
- "inputs": [],
- "name": "withdrawable",
- "outputs": [
- {
- "name": "",
- "type": "bool"
- }
- ],
- "payable": false,
- "stateMutability": "view",
- "type": "function"
}
]
`
diff --git a/core/vm/oracle_contracts.go b/core/vm/oracle_contracts.go
index ddcd6d3f6..130d5bf24 100644
--- a/core/vm/oracle_contracts.go
+++ b/core/vm/oracle_contracts.go
@@ -99,6 +99,9 @@ const (
minBlockIntervalLoc
fineValuesLoc
finedRecordsLoc
+ isConsortiumLoc
+ addressWhitelistLoc
+ whitelistOffsetByAddressLoc
)
func publicKeyToNodeKeyAddress(pkBytes []byte) (common.Address, error) {
@@ -124,7 +127,7 @@ func IdToAddress(id coreTypes.NodeID) common.Address {
return common.BytesToAddress(id.Hash[12:])
}
-// State manipulation helper fro the governance contract.
+// State manipulation helper for the governance contract.
type GovernanceState struct {
StateDB StateDB
}
@@ -984,6 +987,80 @@ func (s *GovernanceState) SetFineRecords(recordHash Bytes32, status bool) {
s.setStateBigInt(loc, big.NewInt(value))
}
+// bool public isConsortium;
+func (s *GovernanceState) IsConsortium() bool {
+ return s.getStateBigInt(big.NewInt(isConsortiumLoc)).Cmp(big.NewInt(0)) > 0
+}
+func (s *GovernanceState) EnableConsortium() {
+ s.setStateBigInt(big.NewInt(isConsortiumLoc), big.NewInt(1))
+}
+
+// address[] public addressWhitelist;
+func (s *GovernanceState) LenWhitelist() *big.Int {
+ return s.getStateBigInt(big.NewInt(addressWhitelistLoc))
+}
+func (s *GovernanceState) AddressWhitelist(index *big.Int) common.Address {
+ arrayBaseLoc := s.getSlotLoc(big.NewInt(addressWhitelistLoc))
+ return common.BigToAddress(s.getStateBigInt(new(big.Int).Add(arrayBaseLoc, index)))
+}
+func (s *GovernanceState) AddressWhitelists() []common.Address {
+ len := s.LenWhitelist()
+ result := make([]common.Address, len.Uint64())
+ for i := 0; i < int(len.Uint64()); i++ {
+ result[i] = s.AddressWhitelist(big.NewInt(int64(i)))
+ }
+ return result
+}
+func (s *GovernanceState) putAddressWhitelist(addr common.Address, offset *big.Int) {
+ arrayBaseLoc := s.getSlotLoc(big.NewInt(addressWhitelistLoc))
+ loc := new(big.Int).Add(arrayBaseLoc, offset)
+ s.setState(common.BigToHash(loc), addr.Hash())
+ s.putWhitelistOffsetByAddress(addr, offset)
+}
+func (s *GovernanceState) AddToWhitelist(addr common.Address) *big.Int {
+ offset := s.WhitelistOffsetByAddress(addr)
+ if offset.Cmp(bigZero) >= 0 {
+ return offset
+ }
+ len := s.getStateBigInt(big.NewInt(addressWhitelistLoc))
+ s.putAddressWhitelist(addr, len)
+ len = new(big.Int).Add(len, big.NewInt(1))
+ s.setStateBigInt(big.NewInt(addressWhitelistLoc), len)
+ return len
+}
+func (s *GovernanceState) DeleteAddressWhitelist(addr common.Address) *big.Int {
+ offset := s.WhitelistOffsetByAddress(addr)
+ if offset.Cmp(bigZero) < 0 {
+ return offset
+ }
+ s.DeleteWhitelistOffsetByAddress(addr)
+ len := s.getStateBigInt(big.NewInt(addressWhitelistLoc))
+ newLen := new(big.Int).Sub(len, big.NewInt(1))
+ if len.Cmp(big.NewInt(1)) > 0 && offset.Cmp(newLen) != 0 {
+ lastAddr := s.AddressWhitelist(newLen)
+ s.putAddressWhitelist(lastAddr, offset)
+ }
+ s.setStateBigInt(
+ big.NewInt(addressWhitelistLoc),
+ newLen,
+ )
+ return len
+}
+
+// mapping(address => int256) whitelistOffsetByAddress
+func (s *GovernanceState) WhitelistOffsetByAddress(addr common.Address) *big.Int {
+ loc := s.getMapLoc(big.NewInt(whitelistOffsetByAddressLoc), addr.Bytes())
+ return new(big.Int).Sub(s.getStateBigInt(loc), big.NewInt(1))
+}
+func (s *GovernanceState) putWhitelistOffsetByAddress(addr common.Address, offset *big.Int) {
+ loc := s.getMapLoc(big.NewInt(whitelistOffsetByAddressLoc), addr.Bytes())
+ s.setStateBigInt(loc, new(big.Int).Add(offset, big.NewInt(1)))
+}
+func (s *GovernanceState) DeleteWhitelistOffsetByAddress(addr common.Address) {
+ loc := s.getMapLoc(big.NewInt(whitelistOffsetByAddressLoc), addr.Bytes())
+ s.setStateBigInt(loc, big.NewInt(0))
+}
+
// Initialize initializes governance contract state.
func (s *GovernanceState) Initialize(config *params.DexconConfig, totalSupply *big.Int) {
if config.NextHalvingSupply.Cmp(totalSupply) <= 0 {
@@ -1009,6 +1086,22 @@ func (s *GovernanceState) Initialize(config *params.DexconConfig, totalSupply *b
// Set DKGRound.
s.SetDKGRound(big.NewInt(int64(dexCore.DKGDelayRound)))
+
+ // Set Whitelist
+ s.setWhitelist(config.IsConsortium)
+}
+
+func (s *GovernanceState) setWhitelist(isConsortium bool) {
+ if isConsortium {
+ s.EnableConsortium()
+ for _, node := range s.Nodes() {
+ address, err := publicKeyToNodeKeyAddress(node.PublicKey)
+ if err != nil {
+ panic(err)
+ }
+ s.AddToWhitelist(address)
+ }
+ }
}
// Register is a helper function for creating genesis state.
@@ -1079,6 +1172,8 @@ func (s *GovernanceState) Configuration() *params.DexconConfig {
RoundLength: s.getStateBigInt(big.NewInt(roundLengthLoc)).Uint64(),
MinBlockInterval: s.getStateBigInt(big.NewInt(minBlockIntervalLoc)).Uint64(),
FineValues: s.FineValues(),
+ AddressWhitelist: s.AddressWhitelists(),
+ IsConsortium: s.getStateBigInt(big.NewInt(isConsortiumLoc)).Uint64() != 0,
}
}
@@ -1098,7 +1193,11 @@ func (s *GovernanceState) UpdateConfiguration(cfg *params.DexconConfig) {
s.setStateBigInt(big.NewInt(roundLengthLoc), big.NewInt(int64(cfg.RoundLength)))
s.setStateBigInt(big.NewInt(minBlockIntervalLoc), big.NewInt(int64(cfg.MinBlockInterval)))
s.SetFineValues(cfg.FineValues)
-
+ if cfg.IsConsortium {
+ for _, addr := range cfg.AddressWhitelist {
+ s.AddToWhitelist(addr)
+ }
+ }
// Calculate set size.
s.CalNotarySetSize()
}
@@ -2274,6 +2373,20 @@ func (g *GovernanceContract) Run(evm *EVM, input []byte, contract *Contract) (re
return nil, errExecutionReverted
}
return g.addDKGSuccess(Success)
+ case "addToWhitelist":
+ var address common.Address
+ if err := method.Inputs.Unpack(&address, arguments); err != nil {
+ return nil, errExecutionReverted
+ }
+ offset, err := g.addToWhitelist(address)
+ if err != nil {
+ return nil, errExecutionReverted
+ }
+ res, err := method.Outputs.Pack(offset)
+ if err != nil {
+ return nil, errExecutionReverted
+ }
+ return res, nil
case "nodesLength":
res, err := method.Outputs.Pack(g.state.LenNodes())
if err != nil {
@@ -2295,6 +2408,20 @@ func (g *GovernanceContract) Run(evm *EVM, input []byte, contract *Contract) (re
return nil, errExecutionReverted
}
return g.proposeCRS(args.Round, args.SignedCRS)
+ case "removeFromWhitelist":
+ var address common.Address
+ if err := method.Inputs.Unpack(&address, arguments); err != nil {
+ return nil, errExecutionReverted
+ }
+ offset, err := g.removeFromWhitelist(address)
+ if err != nil {
+ return nil, errExecutionReverted
+ }
+ res, err := method.Outputs.Pack(offset)
+ if err != nil {
+ return nil, errExecutionReverted
+ }
+ return res, nil
case "report":
args := struct {
Type *big.Int
@@ -2371,6 +2498,12 @@ func (g *GovernanceContract) Run(evm *EVM, input []byte, contract *Contract) (re
return nil, errExecutionReverted
}
return g.updateNodeInfo(args.Name, args.Email, args.Location, args.Url)
+ case "whitelistLength":
+ res, err := method.Outputs.Pack(g.state.LenWhitelist())
+ if err != nil {
+ return nil, errExecutionReverted
+ }
+ return res, nil
case "withdraw":
return g.withdraw()
case "withdrawable":
@@ -2379,11 +2512,21 @@ func (g *GovernanceContract) Run(evm *EVM, input []byte, contract *Contract) (re
return nil, errExecutionReverted
}
return res, nil
-
// --------------------------------
// Solidity auto generated methods.
// --------------------------------
+ case "addressWhitelist":
+ offset := new(big.Int)
+ if err := method.Inputs.Unpack(&offset, arguments); err != nil {
+ return nil, errExecutionReverted
+ }
+ address := g.state.AddressWhitelist(offset)
+ res, err := method.Outputs.Pack(address)
+ if err != nil {
+ return nil, errExecutionReverted
+ }
+ return res, nil
case "blockGasLimit":
res, err := method.Outputs.Pack(g.state.BlockGasLimit())
if err != nil {
@@ -2538,6 +2681,12 @@ func (g *GovernanceContract) Run(evm *EVM, input []byte, contract *Contract) (re
return nil, errExecutionReverted
}
return res, nil
+ case "isConsortium":
+ res, err := method.Outputs.Pack(g.state.IsConsortium())
+ if err != nil {
+ return nil, errExecutionReverted
+ }
+ return res, nil
case "lambdaBA":
res, err := method.Outputs.Pack(g.state.LambdaBA())
if err != nil {
@@ -2694,7 +2843,18 @@ func (g *GovernanceContract) Run(evm *EVM, input []byte, contract *Contract) (re
return nil, errExecutionReverted
}
return res, nil
+ case "whitelistOffsetByAddress":
+ address := common.Address{}
+ if err := method.Inputs.Unpack(&address, arguments); err != nil {
+ return nil, errExecutionReverted
+ }
+ res, err := method.Outputs.Pack(g.state.WhitelistOffsetByAddress(address))
+ if err != nil {
+ return nil, errExecutionReverted
+ }
+ return res, nil
}
+
return nil, errExecutionReverted
}
@@ -2801,6 +2961,22 @@ func (g *GovernanceContract) replaceNodePublicKey(newPublicKey []byte) ([]byte,
return nil, nil
}
+func (g *GovernanceContract) addToWhitelist(addr common.Address) (*big.Int, error) {
+ // Only owner can update whitelist.
+ if g.contract.Caller() != g.state.Owner() {
+ return nil, errExecutionReverted
+ }
+ return g.state.AddToWhitelist(addr), nil
+}
+
+func (g *GovernanceContract) removeFromWhitelist(addr common.Address) (*big.Int, error) {
+ // Only owner can update whitelist.
+ if g.contract.Caller() != g.state.Owner() {
+ return nil, errExecutionReverted
+ }
+ return g.state.DeleteAddressWhitelist(addr), nil
+}
+
func PackProposeCRS(round uint64, signedCRS []byte) ([]byte, error) {
method := GovernanceABI.Name2Method["proposeCRS"]
res, err := method.Inputs.Pack(big.NewInt(int64(round)), signedCRS)
diff --git a/core/vm/oracle_contracts_test.go b/core/vm/oracle_contracts_test.go
index 192628b22..bf2f7c71a 100644
--- a/core/vm/oracle_contracts_test.go
+++ b/core/vm/oracle_contracts_test.go
@@ -1022,6 +1022,137 @@ func (g *GovernanceContractTestSuite) TestMiscVariableReading() {
g.Require().NoError(err)
}
+func (g *GovernanceContractTestSuite) TestIsConsortium() {
+ var isConsortium bool
+
+ _, addr1 := newPrefundAccount(g.stateDB)
+
+ input, err := GovernanceABI.ABI.Pack("isConsortium")
+ g.Require().NoError(err)
+ res, err := g.call(GovernanceContractAddress, addr1, input, big.NewInt(0))
+ g.Require().NoError(err)
+ err = GovernanceABI.ABI.Unpack(&isConsortium, "isConsortium", res)
+ g.Require().NoError(err)
+ g.Require().Equal(false, isConsortium)
+
+ g.s.EnableConsortium()
+ res, err = g.call(GovernanceContractAddress, addr1, input, big.NewInt(0))
+ g.Require().NoError(err)
+ err = GovernanceABI.ABI.Unpack(&isConsortium, "isConsortium", res)
+ g.Require().NoError(err)
+ g.Require().Equal(true, isConsortium)
+}
+
+func (g *GovernanceContractTestSuite) TestUpdateWhitelist() {
+ checkLength := func(expectLen *big.Int) {
+ var length *big.Int
+
+ lenInput, err := GovernanceABI.ABI.Pack("whitelistLength")
+ g.Require().NoError(err)
+ res, err := g.call(GovernanceContractAddress, g.config.Owner, lenInput, big.NewInt(0))
+ err = GovernanceABI.ABI.Unpack(&length, "whitelistLength", res)
+ g.Require().NoError(err)
+ g.Require().Equal(expectLen.Int64(), length.Int64())
+ }
+ check := func(addr common.Address, offset *big.Int) {
+ var resOffset *big.Int
+ var resAddr common.Address
+
+ value := big.NewInt(0)
+ // check offset
+ input, err := GovernanceABI.ABI.Pack("whitelistOffsetByAddress", addr)
+ g.Require().NoError(err)
+ res, err := g.call(GovernanceContractAddress, addr, input, value)
+ g.Require().NoError(err)
+ err = GovernanceABI.ABI.Unpack(&resOffset, "whitelistOffsetByAddress", res)
+ g.Require().NoError(err)
+ g.Require().Equal(offset.Int64(), resOffset.Int64())
+
+ // check address
+ if offset.Cmp(big.NewInt(0)) >= 0 {
+ input, err = GovernanceABI.ABI.Pack("addressWhitelist", offset)
+ res, err = g.call(GovernanceContractAddress, addr, input, value)
+ g.Require().NoError(err)
+ err = GovernanceABI.ABI.Unpack(&resAddr, "addressWhitelist", res)
+ g.Require().NoError(err)
+ g.Require().Equal(addr, resAddr)
+ }
+ }
+ _, addr1 := newPrefundAccount(g.stateDB)
+ _, addr2 := newPrefundAccount(g.stateDB)
+ _, addr3 := newPrefundAccount(g.stateDB)
+
+ input, err := GovernanceABI.ABI.Pack("addToWhitelist", addr1)
+ g.Require().NoError(err)
+
+ // Call with non-owner.
+ _, err = g.call(GovernanceContractAddress, addr1, input, big.NewInt(0))
+ g.Require().NotNil(err)
+ // Call with owner.
+ _, err = g.call(GovernanceContractAddress, g.config.Owner, input, big.NewInt(0))
+ g.Require().NoError(err)
+ checkLength(big.NewInt(1))
+ // duplicated call should not affect
+ _, err = g.call(GovernanceContractAddress, g.config.Owner, input, big.NewInt(0))
+ g.Require().NoError(err)
+ checkLength(big.NewInt(1))
+ // append addr2
+ input, err = GovernanceABI.ABI.Pack("addToWhitelist", addr2)
+ g.Require().NoError(err)
+ _, err = g.call(GovernanceContractAddress, g.config.Owner, input, big.NewInt(0))
+ g.Require().NoError(err)
+
+ checkLength(big.NewInt(2))
+ check(addr1, big.NewInt(0))
+ check(addr2, big.NewInt(1))
+
+ // delete addr2
+ input, err = GovernanceABI.ABI.Pack("removeFromWhitelist", addr2)
+ g.Require().NoError(err)
+ // Call with non-owner.
+ _, err = g.call(GovernanceContractAddress, addr1, input, big.NewInt(0))
+ g.Require().NotNil(err)
+ // Call with owner
+ _, err = g.call(GovernanceContractAddress, g.config.Owner, input, big.NewInt(0))
+ g.Require().NoError(err)
+ check(addr2, big.NewInt(-1))
+ checkLength(big.NewInt(1))
+
+ // append addr2 back
+ input, err = GovernanceABI.ABI.Pack("addToWhitelist", addr2)
+ g.Require().NoError(err)
+ _, err = g.call(GovernanceContractAddress, g.config.Owner, input, big.NewInt(0))
+ g.Require().NoError(err)
+ checkLength(big.NewInt(2))
+ check(addr1, big.NewInt(0))
+ check(addr2, big.NewInt(1))
+
+ // delete addr1
+ input, err = GovernanceABI.ABI.Pack("removeFromWhitelist", addr1)
+ g.Require().NoError(err)
+ _, err = g.call(GovernanceContractAddress, g.config.Owner, input, big.NewInt(0))
+ g.Require().NoError(err)
+ check(addr1, big.NewInt(-1))
+ check(addr2, big.NewInt(0))
+ checkLength(big.NewInt(1))
+
+ // delete addr2
+ input, err = GovernanceABI.ABI.Pack("removeFromWhitelist", addr2)
+ g.Require().NoError(err)
+ _, err = g.call(GovernanceContractAddress, g.config.Owner, input, big.NewInt(0))
+ g.Require().NoError(err)
+ check(addr1, big.NewInt(-1))
+ check(addr2, big.NewInt(-1))
+ checkLength(big.NewInt(0))
+
+ // duplicated delete addr2
+ input, err = GovernanceABI.ABI.Pack("removeFromWhitelist", addr2)
+ g.Require().NoError(err)
+ // delete not in whitelist address
+ input, err = GovernanceABI.ABI.Pack("removeFromWhitelist", addr3)
+ g.Require().NoError(err)
+}
+
func (g *GovernanceContractTestSuite) TestHalvingCondition() {
// TotalSupply 2.5B reached
g.s.MiningHalved()
@@ -1244,6 +1375,66 @@ func (g *GovernanceContractTestSuite) TestResetDKG() {
}
}
+func (g *GovernanceContractTestSuite) TestConsortium() {
+ g.Require().False(g.s.IsConsortium())
+ g.s.EnableConsortium()
+ g.Require().True(g.s.IsConsortium())
+}
+
+func (g *GovernanceContractTestSuite) TestAddWhitelist() {
+ _, addr1 := newPrefundAccount(g.stateDB)
+ _, addr2 := newPrefundAccount(g.stateDB)
+ _, addr3 := newPrefundAccount(g.stateDB)
+ // no address in list
+ expectAddress := g.s.AddressWhitelist(big.NewInt(0))
+ g.Require().Equal(common.Address{}, expectAddress)
+ expectAddrList := g.s.AddressWhitelists()
+ g.Require().Equal([]common.Address{}, expectAddrList)
+
+ // insert addr
+ g.s.AddToWhitelist(addr1)
+ g.s.AddToWhitelist(addr1) // duplicated insertion should be ignored
+ expectAddress = g.s.AddressWhitelist(big.NewInt(0))
+ g.Require().Equal(addr1, expectAddress)
+ expectAddrList = g.s.AddressWhitelists()
+ g.Require().Equal([]common.Address{addr1}, expectAddrList)
+
+ g.s.AddToWhitelist(addr2)
+ expectAddress = g.s.AddressWhitelist(big.NewInt(1))
+ g.Require().Equal(addr2, expectAddress)
+ expectAddrList = g.s.AddressWhitelists()
+ g.Require().Equal([]common.Address{addr1, addr2}, expectAddrList)
+
+ offset := g.s.WhitelistOffsetByAddress(addr1)
+ g.Require().Equal(true, offset.Cmp(big.NewInt(0)) == 0)
+ offset = g.s.WhitelistOffsetByAddress(addr2)
+ g.Require().Equal(true, offset.Cmp(big.NewInt(1)) == 0)
+ offset = g.s.WhitelistOffsetByAddress(addr3)
+ g.Require().Equal(true, offset.Cmp(big.NewInt(-1)) == 0)
+
+ // remove addr
+ g.s.DeleteAddressWhitelist(addr1)
+ g.s.DeleteAddressWhitelist(addr1) // duplicated remove should be ignored
+
+ offset = g.s.WhitelistOffsetByAddress(addr1)
+ g.Require().Equal(true, offset.Cmp(big.NewInt(-1)) == 0)
+ offset = g.s.WhitelistOffsetByAddress(addr2)
+ g.Require().Equal(true, offset.Cmp(big.NewInt(0)) == 0)
+
+ expectAddress = g.s.AddressWhitelist(big.NewInt(0))
+ g.Require().Equal(addr2, expectAddress)
+ expectAddrList = g.s.AddressWhitelists()
+ g.Require().Equal([]common.Address{addr2}, expectAddrList)
+
+ g.s.DeleteAddressWhitelist(addr2)
+
+ offset = g.s.WhitelistOffsetByAddress(addr2)
+ g.Require().Equal(true, offset.Cmp(big.NewInt(-1)) == 0)
+
+ expectAddrList = g.s.AddressWhitelists()
+ g.Require().Equal([]common.Address{}, expectAddrList)
+}
+
func TestGovernanceContract(t *testing.T) {
suite.Run(t, new(GovernanceContractTestSuite))
}
diff --git a/dex/handler.go b/dex/handler.go
index ca26bc6e8..4c1ed9a36 100644
--- a/dex/handler.go
+++ b/dex/handler.go
@@ -41,6 +41,7 @@ import (
"errors"
"fmt"
"math"
+ "math/big"
"sync"
"sync/atomic"
"time"
@@ -55,6 +56,7 @@ import (
"github.com/tangerine-network/go-tangerine/consensus"
"github.com/tangerine-network/go-tangerine/core"
"github.com/tangerine-network/go-tangerine/core/types"
+ "github.com/tangerine-network/go-tangerine/core/vm"
"github.com/tangerine-network/go-tangerine/crypto"
dexDB "github.com/tangerine-network/go-tangerine/dex/db"
"github.com/tangerine-network/go-tangerine/dex/downloader"
@@ -89,6 +91,7 @@ const (
maxAgreementResultBroadcast = 3
maxFinalizedBlockBroadcast = 3
+ checkPeerDuration = 10 * time.Minute
)
// errIncompatibleConfig is returned if the requested protocols and configs are
@@ -349,6 +352,7 @@ func (pm *ProtocolManager) ReportBadPeerChan() chan<- interface{} {
}
func (pm *ProtocolManager) badPeerWatchLoop() {
+ go pm.checkPeerInWhitelist(pm.reportBadPeerChan)
for {
select {
case id := <-pm.reportBadPeerChan:
@@ -360,13 +364,42 @@ func (pm *ProtocolManager) badPeerWatchLoop() {
}
}
+func (pm *ProtocolManager) checkPeerInWhitelist(reportBadPeerChan chan<- interface{}) {
+ for {
+ for id, p := range pm.peers.peers {
+ if !pm.inWhitelist(p) {
+ reportBadPeerChan <- id
+ }
+ }
+ time.Sleep(checkPeerDuration)
+ }
+}
+
func (pm *ProtocolManager) newPeer(pv int, p *p2p.Peer, rw p2p.MsgReadWriter) *peer {
return newPeer(pv, p, newMeteredMsgWriter(rw))
}
+func (pm *ProtocolManager) inWhitelist(p *peer) bool {
+ state, err := pm.blockchain.State()
+ if err != nil {
+ p.Log().Debug("get state fail in checking whitelist", "err", err)
+ return false
+ }
+ govState := vm.GovernanceState{StateDB: state}
+ if !govState.IsConsortium() {
+ return true
+ }
+ address := crypto.PubkeyToAddress(*p.Node().Pubkey())
+ return govState.WhitelistOffsetByAddress(address).Cmp(big.NewInt(0)) >= 0
+}
+
// handle is the callback invoked to manage the life cycle of an eth peer. When
// this function terminates, the peer is disconnected.
func (pm *ProtocolManager) handle(p *peer) error {
+ if !pm.inWhitelist(p) {
+ p.Log().Debug("Peer disconnect: permission denied", "name", p.Name())
+ return p2p.DiscPermissionDenied
+ }
// Ignore maxPeers if this is a trusted peer
if pm.peers.Len() >= pm.maxPeers && !p.Peer.Info().Network.Trusted {
return p2p.DiscTooManyPeers
diff --git a/dex/handler_test.go b/dex/handler_test.go
index 80f36ae9e..f276e1e4a 100644
--- a/dex/handler_test.go
+++ b/dex/handler_test.go
@@ -17,9 +17,12 @@
package dex
import (
+ "fmt"
+ "io/ioutil"
"math"
"math/big"
"math/rand"
+ "net"
"testing"
"github.com/tangerine-network/go-tangerine/common"
@@ -30,6 +33,7 @@ import (
"github.com/tangerine-network/go-tangerine/dex/downloader"
"github.com/tangerine-network/go-tangerine/ethdb"
"github.com/tangerine-network/go-tangerine/p2p"
+ "github.com/tangerine-network/go-tangerine/p2p/enode"
"github.com/tangerine-network/go-tangerine/params"
)
@@ -52,7 +56,7 @@ func TestProtocolCompatibility(t *testing.T) {
for i, tt := range tests {
ProtocolVersions = []uint{tt.version}
- pm, _, err := newTestProtocolManager(tt.mode, 0, nil, nil)
+ pm, _, err := newTestProtocolManager(tt.mode, 0, nil, nil, params.TestChainConfig)
if pm != nil {
defer pm.Stop()
}
@@ -444,3 +448,74 @@ func testGetReceipt(t *testing.T, protocol int) {
t.Errorf("receipts mismatch: %v", err)
}
}
+
+func TestHandlerWithConsoritum62(t *testing.T) { testHandlerWithConsoritum(t, 62) }
+func TestHandlerWithConsoritum63(t *testing.T) { testHandlerWithConsoritum(t, 63) }
+
+func testHandlerWithConsoritum(t *testing.T, version int) {
+ key, err := crypto.GenerateKey()
+ if err != nil {
+ t.Errorf("gen key fail %v", err)
+ }
+
+ // set config and create protocol manager
+ config := params.NewTestChainConig()
+ config.ChainID = big.NewInt(int64(DefaultConfig.NetworkId))
+ config.Dexcon = params.NewTestDexonConfig()
+ config.Dexcon.IsConsortium = true
+ pm, _, err := newTestProtocolManager(downloader.FullSync, 0, nil, nil, config)
+ defer pm.Stop()
+ if err != nil {
+ t.Fatalf("Failed to create protocol manager: %v", err)
+ }
+
+ // create peer
+ pipenet1, pipenet2 := p2p.MsgPipe()
+ defer func() {
+ pipenet1.Close()
+ pipenet2.Close()
+ }()
+ node := enode.NewV4(&key.PublicKey, net.IP{}, 0, 0)
+ peer := pm.newPeer(version, p2p.NewPeerWithEnode(node, "handlerTest", nil), pipenet1)
+
+ // try to call handle, and should get permission denied error
+ if err := pm.handle(peer); err != p2p.DiscPermissionDenied {
+ t.Errorf("Expect get DiscPermissionDenied, but get %v", err)
+ }
+
+ // add address to whitelist, and create new pm
+ address := crypto.PubkeyToAddress(key.PublicKey)
+ config.Dexcon.AddressWhitelist = []common.Address{address}
+ pm2, _, err := newTestProtocolManager(downloader.FullSync, 0, nil, nil, config)
+ defer pm2.Stop()
+
+ if err != nil {
+ t.Fatalf("Failed to create protocol manager: %v", err)
+ }
+ handleErr := make(chan error)
+ go func() {
+ handleErr <- pm2.handle(peer)
+ }()
+ // do the handshake
+ msg, err := pipenet2.ReadMsg()
+ ioutil.ReadAll(msg.Payload)
+ p2p.Send(pipenet2, 0,
+ statusData{
+ ProtocolVersion: uint32(version),
+ NetworkId: config.ChainID.Uint64(),
+ Number: 0,
+ CurrentBlock: common.Hash{},
+ GenesisBlock: pm2.blockchain.Genesis().Hash(),
+ },
+ )
+ // send status code to terminate the handleMsg loop
+ p2p.Send(pipenet2, StatusMsg, struct{}{})
+ err = <-handleErr
+ expectError := fmt.Errorf("%v - %v",
+ errorToString[ErrExtraStatusMsg],
+ "uncontrolled status message",
+ )
+ if err.Error() != expectError.Error() {
+ t.Errorf("err not match, expect: %s, but got: %s", expectError, err)
+ }
+}
diff --git a/dex/helper_test.go b/dex/helper_test.go
index 6e2cd3d77..5e171fef0 100644
--- a/dex/helper_test.go
+++ b/dex/helper_test.go
@@ -110,13 +110,18 @@ func (a *testApp) SubscribeNewFinalizedBlockEvent(
// newTestProtocolManager creates a new protocol manager for testing purposes,
// with the given number of blocks already known, and potential notification
// channels for different events.
-func newTestProtocolManager(mode downloader.SyncMode, blocks int, generator func(int, *core.BlockGen), newtx chan<- []*types.Transaction) (*ProtocolManager, *ethdb.MemDatabase, error) {
+func newTestProtocolManager(mode downloader.SyncMode,
+ blocks int,
+ generator func(int, *core.BlockGen),
+ newtx chan<- []*types.Transaction,
+ chainConfig *params.ChainConfig,
+) (*ProtocolManager, *ethdb.MemDatabase, error) {
var (
evmux = new(event.TypeMux)
engine = ethash.NewFaker()
db = ethdb.NewMemDatabase()
gspec = &core.Genesis{
- Config: params.TestChainConfig,
+ Config: chainConfig,
Alloc: core.GenesisAlloc{testBank: {Balance: big.NewInt(1000000), Staked: big.NewInt(0)}},
}
genesis = gspec.MustCommit(db)
@@ -150,7 +155,7 @@ func newTestProtocolManager(mode downloader.SyncMode, blocks int, generator func
// channels for different events. In case of an error, the constructor force-
// fails the test.
func newTestProtocolManagerMust(t *testing.T, mode downloader.SyncMode, blocks int, generator func(int, *core.BlockGen), newtx chan<- []*types.Transaction) (*ProtocolManager, *ethdb.MemDatabase) {
- pm, db, err := newTestProtocolManager(mode, blocks, generator, newtx)
+ pm, db, err := newTestProtocolManager(mode, blocks, generator, newtx, params.TestChainConfig)
if err != nil {
t.Fatalf("Failed to create protocol manager: %v", err)
}
diff --git a/p2p/peer_error.go b/p2p/peer_error.go
index ab61bfef0..f410b76a8 100644
--- a/p2p/peer_error.go
+++ b/p2p/peer_error.go
@@ -69,6 +69,7 @@ const (
DiscUnexpectedIdentity
DiscSelf
DiscReadTimeout
+ DiscPermissionDenied
DiscSubprotocolError = 0x10
)
diff --git a/params/config.go b/params/config.go
index c884b8cdc..b00fc6ee9 100644
--- a/params/config.go
+++ b/params/config.go
@@ -267,22 +267,24 @@ func (c *CliqueConfig) String() string {
// DexconConfig is the consensus engine configs for DEXON consensus.
type DexconConfig struct {
- GenesisCRSText string `json:"genesisCRSText"`
- Owner common.Address `json:"owner"`
- MinStake *big.Int `json:"minStake"`
- LockupPeriod uint64 `json:"lockupPeriod"`
- MiningVelocity float32 `json:"miningVelocity"`
- NextHalvingSupply *big.Int `json:"nextHalvingSupply"`
- LastHalvedAmount *big.Int `json:"lastHalvedAmount"`
- MinGasPrice *big.Int `json:"minGasPrice"`
- BlockGasLimit uint64 `json:"blockGasLimit"`
- LambdaBA uint64 `json:"lambdaBA"`
- LambdaDKG uint64 `json:"lambdaDKG"`
- NotaryParamAlpha float32 `json:"notaryParamAlpha"`
- NotaryParamBeta float32 `json:"notaryParamBeta"`
- RoundLength uint64 `json:"roundLength"`
- MinBlockInterval uint64 `json:"minBlockInterval"`
- FineValues []*big.Int `json:"fineValues"`
+ GenesisCRSText string `json:"genesisCRSText"`
+ Owner common.Address `json:"owner"`
+ MinStake *big.Int `json:"minStake"`
+ LockupPeriod uint64 `json:"lockupPeriod"`
+ MiningVelocity float32 `json:"miningVelocity"`
+ NextHalvingSupply *big.Int `json:"nextHalvingSupply"`
+ LastHalvedAmount *big.Int `json:"lastHalvedAmount"`
+ MinGasPrice *big.Int `json:"minGasPrice"`
+ BlockGasLimit uint64 `json:"blockGasLimit"`
+ LambdaBA uint64 `json:"lambdaBA"`
+ LambdaDKG uint64 `json:"lambdaDKG"`
+ NotaryParamAlpha float32 `json:"notaryParamAlpha"`
+ NotaryParamBeta float32 `json:"notaryParamBeta"`
+ RoundLength uint64 `json:"roundLength"`
+ MinBlockInterval uint64 `json:"minBlockInterval"`
+ FineValues []*big.Int `json:"fineValues"`
+ IsConsortium bool `json:"isConsortium"`
+ AddressWhitelist []common.Address `json:"addressWhitelist"`
}
type dexconConfigSpecMarshaling struct {
@@ -295,7 +297,7 @@ type dexconConfigSpecMarshaling struct {
// String implements the stringer interface, returning the consensus engine details.
func (d *DexconConfig) String() string {
- return fmt.Sprintf("{GenesisCRSText: %v Owner: %v MinStake: %v LockupPeriod: %v MiningVelocity: %v NextHalvingSupply: %v LastHalvedAmount: %v MinGasPrice: %v BlockGasLimit: %v LambdaBA: %v LambdaDKG: %v NotaryParamAlpha: %v NotaryParamBeta: %v RoundLength: %v MinBlockInterval: %v FineValues: %v}",
+ return fmt.Sprintf("{GenesisCRSText: %v Owner: %v MinStake: %v LockupPeriod: %v MiningVelocity: %v NextHalvingSupply: %v LastHalvedAmount: %v MinGasPrice: %v BlockGasLimit: %v LambdaBA: %v LambdaDKG: %v NotaryParamAlpha: %v NotaryParamBeta: %v RoundLength: %v MinBlockInterval: %v FineValues: %v IsConsortium: %v AddressWhitelist: %v}",
d.GenesisCRSText,
d.Owner,
d.MinStake,
@@ -312,6 +314,8 @@ func (d *DexconConfig) String() string {
d.RoundLength,
d.MinBlockInterval,
d.FineValues,
+ d.IsConsortium,
+ d.AddressWhitelist,
)
}
@@ -552,3 +556,35 @@ func (c *ChainConfig) Rules(num *big.Int) Rules {
IsPetersburg: c.IsPetersburg(num),
}
}
+
+// NewTestChainConfig is the ChainConfig constructor for test
+func NewTestChainConig() *ChainConfig {
+ return &ChainConfig{big.NewInt(1), 0, big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, new(EthashConfig), nil, nil, nil}
+}
+
+func NewTestDexonConfig() *DexconConfig {
+ return &DexconConfig{
+ GenesisCRSText: "Tangerine Testnet",
+ Owner: common.HexToAddress("0x0D54AF942d6bF13870F5CA65D470954f21D3cBE5"),
+ MinStake: new(big.Int).Mul(big.NewInt(1e18), big.NewInt(1e6)),
+ LockupPeriod: 3600,
+ MiningVelocity: 0.18,
+ NextHalvingSupply: new(big.Int).Mul(big.NewInt(1e18), big.NewInt(125e6)),
+ LastHalvedAmount: new(big.Int).Mul(big.NewInt(1e18), big.NewInt(75e6)),
+ MinGasPrice: new(big.Int).Mul(big.NewInt(1e9), big.NewInt(1)),
+ BlockGasLimit: 210000000,
+ LambdaBA: 250,
+ LambdaDKG: 20000,
+ NotaryParamAlpha: 70.5,
+ NotaryParamBeta: 264,
+ RoundLength: 3600,
+ MinBlockInterval: 1000,
+ FineValues: []*big.Int{
+ new(big.Int).Mul(big.NewInt(1e18), big.NewInt(100)),
+ new(big.Int).Mul(big.NewInt(1e18), big.NewInt(1)),
+ new(big.Int).Mul(big.NewInt(1e18), big.NewInt(1e6)),
+ new(big.Int).Mul(big.NewInt(1e18), big.NewInt(1e6)),
+ new(big.Int).Mul(big.NewInt(1e18), big.NewInt(1e6)),
+ },
+ }
+}
diff --git a/params/gen_dexcon_config.go b/params/gen_dexcon_config.go
index 28e2775ff..2a8d84546 100644
--- a/params/gen_dexcon_config.go
+++ b/params/gen_dexcon_config.go
@@ -31,6 +31,8 @@ func (d DexconConfig) MarshalJSON() ([]byte, error) {
RoundLength uint64 `json:"roundLength"`
MinBlockInterval uint64 `json:"minBlockInterval"`
FineValues []*math.HexOrDecimal256 `json:"fineValues"`
+ IsConsortium bool `json:"isConsortium"`
+ AddressWhitelist []common.Address `json:"addressWhitelist"`
}
var enc DexconConfig
enc.GenesisCRSText = d.GenesisCRSText
@@ -54,6 +56,8 @@ func (d DexconConfig) MarshalJSON() ([]byte, error) {
enc.FineValues[k] = (*math.HexOrDecimal256)(v)
}
}
+ enc.IsConsortium = d.IsConsortium
+ enc.AddressWhitelist = d.AddressWhitelist
return json.Marshal(&enc)
}
@@ -76,6 +80,8 @@ func (d *DexconConfig) UnmarshalJSON(input []byte) error {
RoundLength *uint64 `json:"roundLength"`
MinBlockInterval *uint64 `json:"minBlockInterval"`
FineValues []*math.HexOrDecimal256 `json:"fineValues"`
+ IsConsortium *bool `json:"isConsortium"`
+ AddressWhitelist []common.Address `json:"addressWhitelist"`
}
var dec DexconConfig
if err := json.Unmarshal(input, &dec); err != nil {
@@ -132,5 +138,11 @@ func (d *DexconConfig) UnmarshalJSON(input []byte) error {
d.FineValues[k] = (*big.Int)(v)
}
}
+ if dec.IsConsortium != nil {
+ d.IsConsortium = *dec.IsConsortium
+ }
+ if dec.AddressWhitelist != nil {
+ d.AddressWhitelist = dec.AddressWhitelist
+ }
return nil
}