Commit 27392337 authored by zelig's avatar zelig Committed by Jeffrey Wilcke

Registrar and contractInfo handling

* resolver -> common/registrar
  * global registrar name registry interface
  * add Call to resolver backend interface
  * the hashReg and UrlHing contracts now initialised from global registry
  * initialization of contracts uniform
  * improve errors and more econsistent method names
* common/registrar/ethreg: versioned registrar
* integrate new naming and registrar in natspec
* js console api: setGlobalRegistrar, setHashReg, setUrlHint
* js test TestContract uses mining - tests fixed all pass
* eth/backend: allow PoW test mode (small ethash DAG)
* console jsre refers to resolver.abi/addr,
* cmd/geth/contracts.go moved to common/registrar
parent 83ee3944
This diff is collapsed.
......@@ -145,6 +145,7 @@ func newLightweightJSRE(libPath string, client comms.EthereumClient, interactive
js := &jsre{ps1: "> "}
js.wait = make(chan *big.Int)
js.client = client
js.ds = docserver.New("/")
if f == nil {
f = js
......@@ -335,7 +336,6 @@ func (js *jsre) apiBindings(f xeth.Frontend) error {
}
js.re.Eval(`var GlobalRegistrar = eth.contract(` + registrar.GlobalRegistrarAbi + `); registrar = GlobalRegistrar.at("` + registrar.GlobalRegistrarAddr + `");`)
return nil
}
......
......@@ -254,7 +254,7 @@ func TestSignature(t *testing.T) {
}
func TestContract(t *testing.T) {
// t.Skip("contract testing is implemented with mining in ethash test mode. This takes about 7seconds to run. Unskip and run on demand")
t.Skip("contract testing is implemented with mining in ethash test mode. This takes about 7seconds to run. Unskip and run on demand")
tmp, repl, ethereum := testJEthRE(t)
if err := ethereum.Start(); err != nil {
t.Errorf("error starting ethereum: %v", err)
......
......@@ -7,8 +7,14 @@ import (
"os"
"time"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/compiler"
"github.com/ethereum/go-ethereum/common/docserver"
"github.com/ethereum/go-ethereum/common/natspec"
"github.com/ethereum/go-ethereum/common/registrar"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/eth"
"github.com/ethereum/go-ethereum/logger/glog"
"github.com/ethereum/go-ethereum/rlp"
......@@ -26,17 +32,27 @@ const (
var (
// mapping between methods and handlers
AdminMapping = map[string]adminhandler{
"admin_addPeer": (*adminApi).AddPeer,
"admin_peers": (*adminApi).Peers,
"admin_nodeInfo": (*adminApi).NodeInfo,
"admin_exportChain": (*adminApi).ExportChain,
"admin_importChain": (*adminApi).ImportChain,
"admin_verbosity": (*adminApi).Verbosity,
"admin_chainSyncStatus": (*adminApi).ChainSyncStatus,
"admin_setSolc": (*adminApi).SetSolc,
"admin_datadir": (*adminApi).DataDir,
"admin_startRPC": (*adminApi).StartRPC,
"admin_stopRPC": (*adminApi).StopRPC,
"admin_addPeer": (*adminApi).AddPeer,
"admin_peers": (*adminApi).Peers,
"admin_nodeInfo": (*adminApi).NodeInfo,
"admin_exportChain": (*adminApi).ExportChain,
"admin_importChain": (*adminApi).ImportChain,
"admin_verbosity": (*adminApi).Verbosity,
"admin_chainSyncStatus": (*adminApi).ChainSyncStatus,
"admin_setSolc": (*adminApi).SetSolc,
"admin_datadir": (*adminApi).DataDir,
"admin_startRPC": (*adminApi).StartRPC,
"admin_stopRPC": (*adminApi).StopRPC,
"admin_setGlobalRegistrar": (*adminApi).SetGlobalRegistrar,
"admin_setHashReg": (*adminApi).SetHashReg,
"admin_setUrlHint": (*adminApi).SetUrlHint,
"admin_saveInfo": (*adminApi).SaveInfo,
"admin_register": (*adminApi).Register,
"admin_registerUrl": (*adminApi).RegisterUrl,
"admin_startNatSpec": (*adminApi).StartNatSpec,
"admin_stopNatSpec": (*adminApi).StopNatSpec,
"admin_getContractInfo": (*adminApi).GetContractInfo,
"admin_httpGet": (*adminApi).HttpGet,
}
)
......@@ -49,6 +65,7 @@ type adminApi struct {
ethereum *eth.Ethereum
codec codec.Codec
coder codec.ApiCoder
ds *docserver.DocServer
}
// create a new admin api instance
......@@ -58,6 +75,7 @@ func NewAdminApi(xeth *xeth.XEth, ethereum *eth.Ethereum, codec codec.Codec) *ad
ethereum: ethereum,
codec: codec,
coder: codec.New(nil),
ds: docserver.New("/"),
}
}
......@@ -292,3 +310,148 @@ func sleepBlocks(wait chan *big.Int, height *big.Int, timer <-chan time.Time) (n
// time.Sleep(time.Duration(sec) * time.Second)
// return otto.UndefinedValue()
// }
func (self *adminApi) SetGlobalRegistrar(req *shared.Request) (interface{}, error) {
args := new(SetGlobalRegistrarArgs)
if err := self.coder.Decode(req.Params, &args); err != nil {
return nil, shared.NewDecodeParamError(err.Error())
}
sender := common.HexToAddress(args.ContractAddress)
reg := registrar.New(self.xeth)
err := reg.SetGlobalRegistrar(args.NameReg, sender)
if err != nil {
return false, err
}
return registrar.GlobalRegistrarAddr, nil
}
func (self *adminApi) SetHashReg(req *shared.Request) (interface{}, error) {
args := new(SetHashRegArgs)
if err := self.coder.Decode(req.Params, &args); err != nil {
return nil, shared.NewDecodeParamError(err.Error())
}
reg := registrar.New(self.xeth)
sender := common.HexToAddress(args.Sender)
err := reg.SetHashReg(args.HashReg, sender)
if err != nil {
return false, err
}
return registrar.HashRegAddr, nil
}
func (self *adminApi) SetUrlHint(req *shared.Request) (interface{}, error) {
args := new(SetUrlHintArgs)
if err := self.coder.Decode(req.Params, &args); err != nil {
return nil, shared.NewDecodeParamError(err.Error())
}
urlHint := args.UrlHint
sender := common.HexToAddress(args.Sender)
reg := registrar.New(self.xeth)
err := reg.SetUrlHint(urlHint, sender)
if err != nil {
return nil, err
}
return registrar.UrlHintAddr, nil
}
func (self *adminApi) SaveInfo(req *shared.Request) (interface{}, error) {
args := new(SaveInfoArgs)
if err := self.coder.Decode(req.Params, &args); err != nil {
return nil, shared.NewDecodeParamError(err.Error())
}
contenthash, err := compiler.SaveInfo(&args.ContractInfo, args.Filename)
if err != nil {
return nil, err
}
return contenthash.Hex(), nil
}
func (self *adminApi) Register(req *shared.Request) (interface{}, error) {
args := new(RegisterArgs)
if err := self.coder.Decode(req.Params, &args); err != nil {
return nil, shared.NewDecodeParamError(err.Error())
}
sender := common.HexToAddress(args.Sender)
// sender and contract address are passed as hex strings
codeb := self.xeth.CodeAtBytes(args.Address)
codeHash := common.BytesToHash(crypto.Sha3(codeb))
contentHash := common.HexToHash(args.ContentHashHex)
registry := registrar.New(self.xeth)
_, err := registry.SetHashToHash(sender, codeHash, contentHash)
if err != nil {
return false, err
}
return true, nil
}
func (self *adminApi) RegisterUrl(req *shared.Request) (interface{}, error) {
args := new(RegisterUrlArgs)
if err := self.coder.Decode(req.Params, &args); err != nil {
return nil, shared.NewDecodeParamError(err.Error())
}
sender := common.HexToAddress(args.Sender)
registry := registrar.New(self.xeth)
_, err := registry.SetUrlToHash(sender, common.HexToHash(args.ContentHash), args.Url)
if err != nil {
return false, err
}
return true, nil
}
func (self *adminApi) StartNatSpec(req *shared.Request) (interface{}, error) {
self.ethereum.NatSpec = true
return true, nil
}
func (self *adminApi) StopNatSpec(req *shared.Request) (interface{}, error) {
self.ethereum.NatSpec = false
return true, nil
}
func (self *adminApi) GetContractInfo(req *shared.Request) (interface{}, error) {
args := new(GetContractInfoArgs)
if err := self.coder.Decode(req.Params, &args); err != nil {
return nil, shared.NewDecodeParamError(err.Error())
}
infoDoc, err := natspec.FetchDocsForContract(args.Contract, self.xeth, self.ds)
if err != nil {
return nil, err
}
var info interface{}
err = self.coder.Decode(infoDoc, &info)
if err != nil {
return nil, err
}
return info, nil
}
func (self *adminApi) HttpGet(req *shared.Request) (interface{}, error) {
args := new(HttpGetArgs)
if err := self.coder.Decode(req.Params, &args); err != nil {
return nil, shared.NewDecodeParamError(err.Error())
}
resp, err := self.ds.Get(args.Uri, args.Path)
if err != nil {
return nil, err
}
return string(resp), nil
}
......@@ -3,6 +3,7 @@ package api
import (
"encoding/json"
"github.com/ethereum/go-ethereum/common/compiler"
"github.com/ethereum/go-ethereum/rpc/shared"
)
......@@ -154,6 +155,7 @@ type SleepBlocksArgs struct {
}
func (args *SleepBlocksArgs) UnmarshalJSON(b []byte) (err error) {
var obj []interface{}
if err := json.Unmarshal(b, &obj); err != nil {
return shared.NewDecodeParamError(err.Error())
......@@ -171,10 +173,276 @@ func (args *SleepBlocksArgs) UnmarshalJSON(b []byte) (err error) {
if len(obj) >= 2 {
if n, ok := obj[1].(int64); ok {
args.N = n
args.Timeout = n
} else {
return shared.NewInvalidTypeError("N", "not an integer")
}
}
return nil
}
type SetGlobalRegistrarArgs struct {
NameReg string
ContractAddress string
}
func (args *SetGlobalRegistrarArgs) UnmarshalJSON(b []byte) (err error) {
var obj []interface{}
if err := json.Unmarshal(b, &obj); err != nil {
return shared.NewDecodeParamError(err.Error())
}
if len(obj) == 0 {
return shared.NewDecodeParamError("Expected namereg address")
}
if len(obj) >= 1 {
if namereg, ok := obj[0].(string); ok {
args.NameReg = namereg
} else {
return shared.NewInvalidTypeError("NameReg", "not a string")
}
}
if len(obj) >= 2 {
if addr, ok := obj[1].(string); ok {
args.ContractAddress = addr
} else {
return shared.NewInvalidTypeError("ContractAddress", "not a string")
}
}
return nil
}
type SetHashRegArgs struct {
HashReg string
Sender string
}
func (args *SetHashRegArgs) UnmarshalJSON(b []byte) (err error) {
var obj []interface{}
if err := json.Unmarshal(b, &obj); err != nil {
return shared.NewDecodeParamError(err.Error())
}
if len(obj) >= 1 {
if hashreg, ok := obj[0].(string); ok {
args.HashReg = hashreg
} else {
return shared.NewInvalidTypeError("HashReg", "not a string")
}
}
if len(obj) >= 2 {
if sender, ok := obj[1].(string); ok {
args.Sender = sender
} else {
return shared.NewInvalidTypeError("Sender", "not a string")
}
}
return nil
}
type SetUrlHintArgs struct {
UrlHint string
Sender string
}
func (args *SetUrlHintArgs) UnmarshalJSON(b []byte) (err error) {
var obj []interface{}
if err := json.Unmarshal(b, &obj); err != nil {
return shared.NewDecodeParamError(err.Error())
}
if len(obj) >= 1 {
if urlhint, ok := obj[0].(string); ok {
args.UrlHint = urlhint
} else {
return shared.NewInvalidTypeError("UrlHint", "not a string")
}
}
if len(obj) >= 2 {
if sender, ok := obj[1].(string); ok {
args.Sender = sender
} else {
return shared.NewInvalidTypeError("Sender", "not a string")
}
}
return nil
}
type SaveInfoArgs struct {
ContractInfo compiler.ContractInfo
Filename string
}
func (args *SaveInfoArgs) UnmarshalJSON(b []byte) (err error) {
var obj []interface{}
if err := json.Unmarshal(b, &obj); err != nil {
return shared.NewDecodeParamError(err.Error())
}
if len(obj) < 2 {
return shared.NewInsufficientParamsError(len(obj), 2)
}
if jsonraw, err := json.Marshal(obj[0]); err == nil {
if err = json.Unmarshal(jsonraw, &args.ContractInfo); err != nil {
return err
}
} else {
return err
}
if filename, ok := obj[1].(string); ok {
args.Filename = filename
} else {
return shared.NewInvalidTypeError("Filename", "not a string")
}
return nil
}
type RegisterArgs struct {
Sender string
Address string
ContentHashHex string
}
func (args *RegisterArgs) UnmarshalJSON(b []byte) (err error) {
var obj []interface{}
if err := json.Unmarshal(b, &obj); err != nil {
return shared.NewDecodeParamError(err.Error())
}
if len(obj) < 3 {
return shared.NewInsufficientParamsError(len(obj), 3)
}
if len(obj) >= 1 {
if sender, ok := obj[0].(string); ok {
args.Sender = sender
} else {
return shared.NewInvalidTypeError("Sender", "not a string")
}
}
if len(obj) >= 2 {
if address, ok := obj[1].(string); ok {
args.Address = address
} else {
return shared.NewInvalidTypeError("Address", "not a string")
}
}
if len(obj) >= 3 {
if hex, ok := obj[2].(string); ok {
args.ContentHashHex = hex
} else {
return shared.NewInvalidTypeError("ContentHashHex", "not a string")
}
}
return nil
}
type RegisterUrlArgs struct {
Sender string
ContentHash string
Url string
}
func (args *RegisterUrlArgs) UnmarshalJSON(b []byte) (err error) {
var obj []interface{}
if err := json.Unmarshal(b, &obj); err != nil {
return shared.NewDecodeParamError(err.Error())
}
if len(obj) >= 1 {
if sender, ok := obj[1].(string); ok {
args.Sender = sender
} else {
return shared.NewInvalidTypeError("Sender", "not a string")
}
}
if sender, ok := obj[1].(string); ok {
args.ContentHash = sender
} else {
return shared.NewInvalidTypeError("ContentHash", "not a string")
}
if len(obj) >= 3 {
if sender, ok := obj[2].(string); ok {
args.Url = sender
} else {
return shared.NewInvalidTypeError("Url", "not a string")
}
}
return nil
}
type GetContractInfoArgs struct {
Contract string
}
func (args *GetContractInfoArgs) UnmarshalJSON(b []byte) (err error) {
var obj []interface{}
if err := json.Unmarshal(b, &obj); err != nil {
return shared.NewDecodeParamError(err.Error())
}
if len(obj) < 1 {
return shared.NewInsufficientParamsError(len(obj), 1)
}
if len(obj) >= 1 {
if contract, ok := obj[0].(string); ok {
args.Contract = contract
} else {
return shared.NewInvalidTypeError("Timeout", "not an integer")
return shared.NewInvalidTypeError("Contract", "not a string")
}
}
return nil
}
type HttpGetArgs struct {
Uri string
Path string
}
func (args *HttpGetArgs) UnmarshalJSON(b []byte) (err error) {
var obj []interface{}
if err := json.Unmarshal(b, &obj); err != nil {
return shared.NewDecodeParamError(err.Error())
}
if len(obj) < 1 {
return shared.NewInsufficientParamsError(len(obj), 1)
}
if len(obj) >= 1 {
if uri, ok := obj[0].(string); ok {
args.Uri = uri
} else {
return shared.NewInvalidTypeError("Uri", "not a string")
}
}
if len(obj) >= 2 {
if path, ok := obj[1].(string); ok {
args.Path = path
} else {
return shared.NewInvalidTypeError("Path", "not a string")
}
}
return nil
}
......@@ -53,7 +53,71 @@ web3._extend({
params: 0,
inputFormatter: [],
outputFormatter: web3._extend.formatters.formatOutputBool
}),
new web3._extend.Method({
name: 'setGlobalRegistrar',
call: 'admin_setGlobalRegistrar',
params: 2,
inputFormatter: [web3._extend.utils.formatInputString,web3._extend.utils.formatInputString],
outputFormatter: web3._extend.formatters.formatOutputString
}),
new web3._extend.Method({
name: 'setHashReg',
call: 'admin_setHashReg',
params: 2,
inputFormatter: [web3._extend.utils.formatInputString,web3._extend.utils.formatInputString],
outputFormatter: web3._extend.formatters.formatOutputString
}),
new web3._extend.Method({
name: 'saveInfo',
call: 'admin_saveInfo',
params: 2,
inputFormatter: [function(obj) { return obj; },web3._extend.utils.formatInputString],
outputFormatter: web3._extend.formatters.formatOutputString
}),
new web3._extend.Method({
name: 'register',
call: 'admin_register',
params: 2,
inputFormatter: [web3._extend.utils.formatInputString,web3._extend.utils.formatInputString],
outputFormatter: web3._extend.formatters.formatOutputBool
}),
new web3._extend.Method({
name: 'registerUrl',
call: 'admin_registerUrl',
params: 3,
inputFormatter: [web3._extend.utils.formatInputString,web3._extend.utils.formatInputString,web3._extend.utils.formatInputString],
outputFormatter: web3._extend.formatters.formatOutputBool
}),
new web3._extend.Method({
name: 'StartNatSpec',
call: 'admin_startNatSpec',
params: 0,
inputFormatter: [],
outputFormatter: web3._extend.formatters.formatOutputBool
}),
new web3._extend.Method({
name: 'StopNatSpec',
call: 'admin_stopNatSpec',
params: 0,
inputFormatter: [],
outputFormatter: web3._extend.formatters.formatOutputBool
}),
new web3._extend.Method({
name: 'getContractInfo',
call: 'admin_getContractInfo',
params: 1,
inputFormatter: [web3._extend.utils.formatInputString],
outputFormatter: function(obj) { return json.parse(obj); }
}),
new web3._extend.Method({
name: 'httpGet',
call: 'admin_httpGet',
params: 2,
inputFormatter: [web3._extend.utils.formatInputString,web3._extend.utils.formatInputString],
outputFormatter: web3._extend.formatters.formatOutputString
})
],
properties:
[
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment