aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWei-Ning Huang <w@dexon.org>2019-04-26 19:05:48 +0800
committerWei-Ning Huang <w@byzantine-lab.io>2019-06-15 22:09:56 +0800
commit2d3b0088eb051aa157046c396024a51cac5d87fc (patch)
treeead1bc332e2c5dd03f7c3ba738765b15a069575a
parent264000767891fbeb2360e495d195a0820115ad85 (diff)
downloadgo-tangerine-2d3b0088eb051aa157046c396024a51cac5d87fc.tar.gz
go-tangerine-2d3b0088eb051aa157046c396024a51cac5d87fc.tar.zst
go-tangerine-2d3b0088eb051aa157046c396024a51cac5d87fc.zip
core: vm: implement transferNodeOwnershipByFoundation (#399)
-rw-r--r--core/vm/oracle_contract_abi.go18
-rw-r--r--core/vm/oracle_contracts.go41
-rw-r--r--core/vm/oracle_contracts_test.go34
3 files changed, 93 insertions, 0 deletions
diff --git a/core/vm/oracle_contract_abi.go b/core/vm/oracle_contract_abi.go
index 35d0f16d1..0516f3891 100644
--- a/core/vm/oracle_contract_abi.go
+++ b/core/vm/oracle_contract_abi.go
@@ -961,6 +961,24 @@ const GovernanceABIJSON = `
"constant": false,
"inputs": [
{
+ "name": "OldOwner",
+ "type": "address"
+ },
+ {
+ "name": "NewOwner",
+ "type": "address"
+ }
+ ],
+ "name": "transferNodeOwnershipByFoundation",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
"name": "NewPublicKey",
"type": "bytes"
}
diff --git a/core/vm/oracle_contracts.go b/core/vm/oracle_contracts.go
index 4434dcf5c..47a680455 100644
--- a/core/vm/oracle_contracts.go
+++ b/core/vm/oracle_contracts.go
@@ -2300,6 +2300,15 @@ func (g *GovernanceContract) Run(evm *EVM, input []byte, contract *Contract) (re
return nil, errExecutionReverted
}
return g.transferNodeOwnership(newOwner)
+ case "transferNodeOwnershipByFoundation":
+ args := struct {
+ OldOwner common.Address
+ NewOwner common.Address
+ }{}
+ if err := method.Inputs.Unpack(&args, arguments); err != nil {
+ return nil, errExecutionReverted
+ }
+ return g.transferNodeOwnershipByFoundation(args.OldOwner, args.NewOwner)
case "unstake":
amount := new(big.Int)
if err := method.Inputs.Unpack(&amount, arguments); err != nil {
@@ -2679,6 +2688,38 @@ func (g *GovernanceContract) transferNodeOwnership(newOwner common.Address) ([]b
return nil, nil
}
+func (g *GovernanceContract) transferNodeOwnershipByFoundation(oldOwner, newOwner common.Address) ([]byte, error) {
+ // Only owner can update configuration.
+ if g.contract.Caller() != g.state.Owner() {
+ return nil, errExecutionReverted
+ }
+
+ if newOwner == (common.Address{}) {
+ return nil, errExecutionReverted
+ }
+
+ offset := g.state.NodesOffsetByAddress(oldOwner)
+ if offset.Cmp(big.NewInt(0)) < 0 {
+ return nil, errExecutionReverted
+ }
+
+ newOffset := g.state.NodesOffsetByAddress(newOwner)
+ if newOffset.Cmp(big.NewInt(0)) >= 0 {
+ return nil, errExecutionReverted
+ }
+
+ node := g.state.Node(offset)
+ g.state.DeleteNodeOffsets(node)
+
+ node.Owner = newOwner
+ g.state.PutNodeOffsets(node, offset)
+ g.state.UpdateNode(offset, node)
+
+ g.state.emitNodeOwnershipTransfered(oldOwner, newOwner)
+
+ return nil, nil
+}
+
func (g *GovernanceContract) replaceNodePublicKey(newPublicKey []byte) ([]byte, error) {
caller := g.contract.Caller()
diff --git a/core/vm/oracle_contracts_test.go b/core/vm/oracle_contracts_test.go
index be1e2a27d..5be893f95 100644
--- a/core/vm/oracle_contracts_test.go
+++ b/core/vm/oracle_contracts_test.go
@@ -322,6 +322,40 @@ func (g *OracleContractsTestSuite) TestTransferNodeOwnership() {
g.Require().Error(err)
}
+func (g *OracleContractsTestSuite) TestTransferNodeOwnershipByFoundation() {
+ 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)
+
+ _, newAddr := newPrefundAccount(g.stateDB)
+
+ // Call with not valid new owner.
+ input, err = GovernanceABI.ABI.Pack("transferNodeOwnershipByFoundation", common.Address{}, newAddr)
+ g.Require().NoError(err)
+ _, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0))
+ g.Require().NotNil(err)
+
+ input, err = GovernanceABI.ABI.Pack("transferNodeOwnershipByFoundation", addr, newAddr)
+ g.Require().NoError(err)
+
+ // Call with gov owner.
+ _, noneOwner := newPrefundAccount(g.stateDB)
+ _, err = g.call(GovernanceContractAddress, noneOwner, input, big.NewInt(0))
+ g.Require().Error(err)
+
+ // Call with gov owner.
+ _, err = g.call(GovernanceContractAddress, g.config.Owner, input, big.NewInt(0))
+ g.Require().NoError(err)
+ g.Require().Equal(-1, int(g.s.NodesOffsetByAddress(addr).Int64()))
+ g.Require().Equal(0, int(g.s.NodesOffsetByNodeKeyAddress(addr).Int64()))
+ g.Require().Equal(0, int(g.s.NodesOffsetByAddress(newAddr).Int64()))
+}
+
func (g *OracleContractsTestSuite) TestReplaceNodePublicKey() {
privKey, addr := newPrefundAccount(g.stateDB)
pk := crypto.FromECDSAPub(&privKey.PublicKey)