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 ...@@ -145,6 +145,7 @@ func newLightweightJSRE(libPath string, client comms.EthereumClient, interactive
js := &jsre{ps1: "> "} js := &jsre{ps1: "> "}
js.wait = make(chan *big.Int) js.wait = make(chan *big.Int)
js.client = client js.client = client
js.ds = docserver.New("/")
if f == nil { if f == nil {
f = js f = js
...@@ -335,7 +336,6 @@ func (js *jsre) apiBindings(f xeth.Frontend) error { ...@@ -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 + `");`) js.re.Eval(`var GlobalRegistrar = eth.contract(` + registrar.GlobalRegistrarAbi + `); registrar = GlobalRegistrar.at("` + registrar.GlobalRegistrarAddr + `");`)
return nil return nil
} }
......
...@@ -254,7 +254,7 @@ func TestSignature(t *testing.T) { ...@@ -254,7 +254,7 @@ func TestSignature(t *testing.T) {
} }
func TestContract(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) tmp, repl, ethereum := testJEthRE(t)
if err := ethereum.Start(); err != nil { if err := ethereum.Start(); err != nil {
t.Errorf("error starting ethereum: %v", err) t.Errorf("error starting ethereum: %v", err)
......
...@@ -7,8 +7,14 @@ import ( ...@@ -7,8 +7,14 @@ import (
"os" "os"
"time" "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"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/eth" "github.com/ethereum/go-ethereum/eth"
"github.com/ethereum/go-ethereum/logger/glog" "github.com/ethereum/go-ethereum/logger/glog"
"github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rlp"
...@@ -37,6 +43,16 @@ var ( ...@@ -37,6 +43,16 @@ var (
"admin_datadir": (*adminApi).DataDir, "admin_datadir": (*adminApi).DataDir,
"admin_startRPC": (*adminApi).StartRPC, "admin_startRPC": (*adminApi).StartRPC,
"admin_stopRPC": (*adminApi).StopRPC, "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 { ...@@ -49,6 +65,7 @@ type adminApi struct {
ethereum *eth.Ethereum ethereum *eth.Ethereum
codec codec.Codec codec codec.Codec
coder codec.ApiCoder coder codec.ApiCoder
ds *docserver.DocServer
} }
// create a new admin api instance // create a new admin api instance
...@@ -58,6 +75,7 @@ func NewAdminApi(xeth *xeth.XEth, ethereum *eth.Ethereum, codec codec.Codec) *ad ...@@ -58,6 +75,7 @@ func NewAdminApi(xeth *xeth.XEth, ethereum *eth.Ethereum, codec codec.Codec) *ad
ethereum: ethereum, ethereum: ethereum,
codec: codec, codec: codec,
coder: codec.New(nil), 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 ...@@ -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) // time.Sleep(time.Duration(sec) * time.Second)
// return otto.UndefinedValue() // 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 ...@@ -3,6 +3,7 @@ package api
import ( import (
"encoding/json" "encoding/json"
"github.com/ethereum/go-ethereum/common/compiler"
"github.com/ethereum/go-ethereum/rpc/shared" "github.com/ethereum/go-ethereum/rpc/shared"
) )
...@@ -154,6 +155,7 @@ type SleepBlocksArgs struct { ...@@ -154,6 +155,7 @@ type SleepBlocksArgs struct {
} }
func (args *SleepBlocksArgs) UnmarshalJSON(b []byte) (err error) { func (args *SleepBlocksArgs) UnmarshalJSON(b []byte) (err error) {
var obj []interface{} var obj []interface{}
if err := json.Unmarshal(b, &obj); err != nil { if err := json.Unmarshal(b, &obj); err != nil {
return shared.NewDecodeParamError(err.Error()) return shared.NewDecodeParamError(err.Error())
...@@ -171,10 +173,276 @@ func (args *SleepBlocksArgs) UnmarshalJSON(b []byte) (err error) { ...@@ -171,10 +173,276 @@ func (args *SleepBlocksArgs) UnmarshalJSON(b []byte) (err error) {
if len(obj) >= 2 { if len(obj) >= 2 {
if n, ok := obj[1].(int64); ok { 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 { } else {
return shared.NewInvalidTypeError("Timeout", "not an integer") 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("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 return nil
} }
...@@ -53,7 +53,71 @@ web3._extend({ ...@@ -53,7 +53,71 @@ web3._extend({
params: 0, params: 0,
inputFormatter: [], inputFormatter: [],
outputFormatter: web3._extend.formatters.formatOutputBool 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: 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