aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWei-Ning Huang <w@byzantine-lab.io>2019-06-17 15:42:47 +0800
committerWei-Ning Huang <w@byzantine-lab.io>2019-09-17 16:57:30 +0800
commit0f7b223fa10ec41f1d2342d3b5de9a9f6a7432ce (patch)
tree6c72fa1f326801f6acb91d768d660cbb383771c0
parent8dddb63449d3d1439357a3bccd5c3cf828136ea5 (diff)
downloadgo-tangerine-0f7b223fa10ec41f1d2342d3b5de9a9f6a7432ce.tar.gz
go-tangerine-0f7b223fa10ec41f1d2342d3b5de9a9f6a7432ce.tar.zst
go-tangerine-0f7b223fa10ec41f1d2342d3b5de9a9f6a7432ce.zip
core: vm: add updateNodeInfo governance method
-rw-r--r--core/vm/oracle_contract_abi.go184
-rw-r--r--core/vm/oracle_contracts.go79
-rw-r--r--core/vm/oracle_contracts_test.go24
3 files changed, 201 insertions, 86 deletions
diff --git a/core/vm/oracle_contract_abi.go b/core/vm/oracle_contract_abi.go
index 53c3edc1e..535161bd4 100644
--- a/core/vm/oracle_contract_abi.go
+++ b/core/vm/oracle_contract_abi.go
@@ -947,11 +947,11 @@ const GovernanceABIJSON = `
"constant": false,
"inputs": [
{
- "name": "NewOwner",
- "type": "address"
+ "name": "Complaint",
+ "type": "bytes"
}
],
- "name": "transferNodeOwnership",
+ "name": "addDKGComplaint",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
@@ -961,15 +961,11 @@ const GovernanceABIJSON = `
"constant": false,
"inputs": [
{
- "name": "OldOwner",
- "type": "address"
- },
- {
- "name": "NewOwner",
- "type": "address"
+ "name": "PublicKey",
+ "type": "bytes"
}
],
- "name": "transferNodeOwnershipByFoundation",
+ "name": "addDKGMasterPublicKey",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
@@ -979,43 +975,39 @@ const GovernanceABIJSON = `
"constant": false,
"inputs": [
{
- "name": "NewPublicKey",
+ "name": "MPKReady",
"type": "bytes"
}
],
- "name": "replaceNodePublicKey",
+ "name": "addDKGMPKReady",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
- "constant": true,
- "inputs": [],
- "name": "nodesLength",
- "outputs": [
+ "constant": false,
+ "inputs": [
{
- "name": "",
- "type": "uint256"
+ "name": "Finalize",
+ "type": "bytes"
}
],
+ "name": "addDKGFinalize",
+ "outputs": [],
"payable": false,
- "stateMutability": "view",
+ "stateMutability": "nonpayable",
"type": "function"
},
{
"constant": false,
"inputs": [
{
- "name": "Round",
- "type": "uint256"
- },
- {
- "name": "SignedCRS",
+ "name": "Success",
"type": "bytes"
}
],
- "name": "proposeCRS",
+ "name": "addDKGSuccess",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
@@ -1025,39 +1017,43 @@ const GovernanceABIJSON = `
"constant": false,
"inputs": [
{
- "name": "Complaint",
- "type": "bytes"
+ "name": "NodeAddress",
+ "type": "address"
}
],
- "name": "addDKGComplaint",
+ "name": "payFine",
"outputs": [],
- "payable": false,
- "stateMutability": "nonpayable",
+ "payable": true,
+ "stateMutability": "payable",
"type": "function"
},
{
- "constant": false,
- "inputs": [
+ "constant": true,
+ "inputs": [],
+ "name": "nodesLength",
+ "outputs": [
{
- "name": "PublicKey",
- "type": "bytes"
+ "name": "",
+ "type": "uint256"
}
],
- "name": "addDKGMasterPublicKey",
- "outputs": [],
"payable": false,
- "stateMutability": "nonpayable",
+ "stateMutability": "view",
"type": "function"
},
{
"constant": false,
"inputs": [
{
- "name": "MPKReady",
+ "name": "Round",
+ "type": "uint256"
+ },
+ {
+ "name": "SignedCRS",
"type": "bytes"
}
],
- "name": "addDKGMPKReady",
+ "name": "proposeCRS",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
@@ -1067,11 +1063,19 @@ const GovernanceABIJSON = `
"constant": false,
"inputs": [
{
- "name": "Finalize",
+ "name": "Type",
+ "type": "uint256"
+ },
+ {
+ "name": "Arg1",
+ "type": "bytes"
+ },
+ {
+ "name": "Arg2",
"type": "bytes"
}
],
- "name": "addDKGFinalize",
+ "name": "report",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
@@ -1081,11 +1085,11 @@ const GovernanceABIJSON = `
"constant": false,
"inputs": [
{
- "name": "Success",
+ "name": "NewSignedCRS",
"type": "bytes"
}
],
- "name": "addDKGSuccess",
+ "name": "resetDKG",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
@@ -1123,6 +1127,20 @@ const GovernanceABIJSON = `
},
{
"constant": false,
+ "inputs": [
+ {
+ "name": "NewPublicKey",
+ "type": "bytes"
+ }
+ ],
+ "name": "replaceNodePublicKey",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": false,
"inputs": [],
"name": "stake",
"outputs": [],
@@ -1134,11 +1152,11 @@ const GovernanceABIJSON = `
"constant": false,
"inputs": [
{
- "name": "Amount",
- "type": "uint256"
+ "name": "NewOwner",
+ "type": "address"
}
],
- "name": "unstake",
+ "name": "transferNodeOwnership",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
@@ -1146,58 +1164,57 @@ const GovernanceABIJSON = `
},
{
"constant": false,
- "inputs": [],
- "name": "withdraw",
- "outputs": [],
- "payable": false,
- "stateMutability": "nonpayable",
- "type": "function"
- },
- {
- "constant": true,
- "inputs": [],
- "name": "withdrawable",
- "outputs": [
+ "inputs": [
{
- "name": "",
- "type": "bool"
+ "name": "OldOwner",
+ "type": "address"
+ },
+ {
+ "name": "NewOwner",
+ "type": "address"
}
],
+ "name": "transferNodeOwnershipByFoundation",
+ "outputs": [],
"payable": false,
- "stateMutability": "view",
+ "stateMutability": "nonpayable",
"type": "function"
},
{
"constant": false,
"inputs": [
{
- "name": "NodeAddress",
- "type": "address"
+ "name": "Amount",
+ "type": "uint256"
}
],
- "name": "payFine",
+ "name": "unstake",
"outputs": [],
- "payable": true,
- "stateMutability": "payable",
+ "payable": false,
+ "stateMutability": "nonpayable",
"type": "function"
},
{
"constant": false,
"inputs": [
{
- "name": "Type",
- "type": "uint256"
+ "name": "Name",
+ "type": "string"
},
{
- "name": "Arg1",
- "type": "bytes"
+ "name": "Email",
+ "type": "string"
},
{
- "name": "Arg2",
- "type": "bytes"
+ "name": "Location",
+ "type": "string"
+ },
+ {
+ "name": "Url",
+ "type": "string"
}
],
- "name": "report",
+ "name": "updateNodeInfo",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
@@ -1205,16 +1222,25 @@ const GovernanceABIJSON = `
},
{
"constant": false,
- "inputs": [
+ "inputs": [],
+ "name": "withdraw",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "withdrawable",
+ "outputs": [
{
- "name": "NewSignedCRS",
- "type": "bytes"
+ "name": "",
+ "type": "bool"
}
],
- "name": "resetDKG",
- "outputs": [],
"payable": false,
- "stateMutability": "nonpayable",
+ "stateMutability": "view",
"type": "function"
}
]
diff --git a/core/vm/oracle_contracts.go b/core/vm/oracle_contracts.go
index 05d4bd821..484ed82b8 100644
--- a/core/vm/oracle_contracts.go
+++ b/core/vm/oracle_contracts.go
@@ -465,19 +465,48 @@ func (s *GovernanceState) UpdateNode(index *big.Int, n *nodeInfo) {
// Update set size.
s.CalNotarySetSize()
}
+func (s *GovernanceState) EraseNode(index *big.Int) {
+ s.UpdateNode(index, &nodeInfo{
+ Staked: big.NewInt(0),
+ Fined: big.NewInt(0),
+ Unstaked: big.NewInt(0),
+ UnstakedAt: big.NewInt(0),
+ })
+}
func (s *GovernanceState) PopLastNode() {
// Decrease length by 1.
arrayLength := s.LenNodes()
newArrayLength := new(big.Int).Sub(arrayLength, big.NewInt(1))
s.setStateBigInt(big.NewInt(nodesLoc), newArrayLength)
- s.UpdateNode(newArrayLength, &nodeInfo{
- Staked: big.NewInt(0),
- Fined: big.NewInt(0),
- Unstaked: big.NewInt(0),
- UnstakedAt: big.NewInt(0),
- })
+ s.EraseNode(newArrayLength)
}
+func (s *GovernanceState) UpdateNodeInfo(index *big.Int, n *nodeInfo) {
+ arrayBaseLoc := s.getSlotLoc(big.NewInt(nodesLoc))
+ elementBaseLoc := new(big.Int).Add(arrayBaseLoc,
+ new(big.Int).Mul(index, big.NewInt(nodeStructSize)))
+
+ // Name.
+ loc := new(big.Int).Add(elementBaseLoc, big.NewInt(4))
+ s.eraseBytes(loc)
+ s.writeBytes(loc, []byte(n.Name))
+
+ // Email.
+ loc = new(big.Int).Add(elementBaseLoc, big.NewInt(5))
+ s.eraseBytes(loc)
+ s.writeBytes(loc, []byte(n.Email))
+
+ // Location.
+ loc = new(big.Int).Add(elementBaseLoc, big.NewInt(6))
+ s.eraseBytes(loc)
+ s.writeBytes(loc, []byte(n.Location))
+
+ // Url.
+ loc = new(big.Int).Add(elementBaseLoc, big.NewInt(7))
+ s.eraseBytes(loc)
+ s.writeBytes(loc, []byte(n.Url))
+}
+
func (s *GovernanceState) Nodes() []*nodeInfo {
var nodes []*nodeInfo
for i := int64(0); i < int64(s.LenNodes().Uint64()); i++ {
@@ -1728,7 +1757,7 @@ func (g *GovernanceContract) register(
publicKey []byte, name, email, location, url string) ([]byte, error) {
// Reject invalid inputs.
- if len(name) >= 32 || len(email) >= 32 || len(location) >= 32 || len(url) >= 128 {
+ if len(name) >= 64 || len(email) >= 128 || len(location) >= 64 || len(url) >= 128 {
return nil, errExecutionReverted
}
@@ -1838,6 +1867,31 @@ func (g *GovernanceContract) unstake(amount *big.Int) ([]byte, error) {
return g.useGas(GovernanceActionGasCost)
}
+func (g *GovernanceContract) updateNodeInfo(
+ name, email, location, url string) ([]byte, error) {
+
+ caller := g.contract.Caller()
+
+ offset := g.state.NodesOffsetByAddress(caller)
+ if offset.Cmp(big.NewInt(0)) < 0 {
+ return nil, errExecutionReverted
+ }
+
+ // Reject invalid inputs.
+ if len(name) >= 64 || len(email) >= 128 || len(location) >= 64 || len(url) >= 128 {
+ return nil, errExecutionReverted
+ }
+
+ g.state.UpdateNodeInfo(offset, &nodeInfo{
+ Name: name,
+ Email: email,
+ Location: location,
+ Url: url,
+ })
+
+ return g.useGas(GovernanceActionGasCost)
+}
+
func (g *GovernanceContract) withdraw() ([]byte, error) {
if !g.withdrawable() {
return nil, errExecutionReverted
@@ -2323,6 +2377,17 @@ func (g *GovernanceContract) Run(evm *EVM, input []byte, contract *Contract) (re
return nil, errExecutionReverted
}
return g.updateConfiguration(&cfg)
+ case "updateNodeInfo":
+ args := struct {
+ Name string
+ Email string
+ Location string
+ Url string
+ }{}
+ if err := method.Inputs.Unpack(&args, arguments); err != nil {
+ return nil, errExecutionReverted
+ }
+ return g.updateNodeInfo(args.Name, args.Email, args.Location, args.Url)
case "withdraw":
return g.withdraw()
case "withdrawable":
diff --git a/core/vm/oracle_contracts_test.go b/core/vm/oracle_contracts_test.go
index 9a2c151bf..7c892ac10 100644
--- a/core/vm/oracle_contracts_test.go
+++ b/core/vm/oracle_contracts_test.go
@@ -402,6 +402,30 @@ func (g *OracleContractsTestSuite) TestReplaceNodePublicKey() {
g.Require().Error(err)
}
+func (g *OracleContractsTestSuite) TestUpdateNodeInfo() {
+ privKey, addr := newPrefundAccount(g.stateDB)
+ pk := crypto.FromECDSAPub(&privKey.PublicKey)
+
+ amount := new(big.Int).Mul(big.NewInt(1e18), big.NewInt(1e6))
+ input, err := GovernanceABI.ABI.Pack("register", pk, "Test1", "test1@dexon.org", "Taipei", "https://dexon.org")
+ g.Require().NoError(err)
+ _, err = g.call(GovernanceContractAddress, addr, input, amount)
+ g.Require().NoError(err)
+
+ input, err = GovernanceABI.ABI.Pack("updateNodeInfo", "New Name", "new@dexon.org", "New Location", "https://new.dexon.org")
+ g.Require().NoError(err)
+
+ _, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0))
+ g.Require().NoError(err)
+
+ offset := g.s.NodesOffsetByAddress(addr)
+ node := g.s.Node(offset)
+ g.Require().Equal("New Name", node.Name)
+ g.Require().Equal("new@dexon.org", node.Email)
+ g.Require().Equal("New Location", node.Location)
+ g.Require().Equal("https://new.dexon.org", node.Url)
+}
+
func (g *OracleContractsTestSuite) TestStakingMechanism() {
privKey, addr := newPrefundAccount(g.stateDB)
pk := crypto.FromECDSAPub(&privKey.PublicKey)