diff options
author | zelig <viktor.tron@gmail.com> | 2015-09-22 16:34:58 +0800 |
---|---|---|
committer | zelig <viktor.tron@gmail.com> | 2015-10-22 06:22:39 +0800 |
commit | 8b81ad1fc40080af441c0c6df94f0b2ea46e320b (patch) | |
tree | 7d8817ec84be38b911f967f1ecd5618d02e4caa9 /common | |
parent | 58d0752fdd1c7363fb1a127cd7e0a86d7602be02 (diff) | |
download | go-tangerine-8b81ad1fc40080af441c0c6df94f0b2ea46e320b.tar go-tangerine-8b81ad1fc40080af441c0c6df94f0b2ea46e320b.tar.gz go-tangerine-8b81ad1fc40080af441c0c6df94f0b2ea46e320b.tar.bz2 go-tangerine-8b81ad1fc40080af441c0c6df94f0b2ea46e320b.tar.lz go-tangerine-8b81ad1fc40080af441c0c6df94f0b2ea46e320b.tar.xz go-tangerine-8b81ad1fc40080af441c0c6df94f0b2ea46e320b.tar.zst go-tangerine-8b81ad1fc40080af441c0c6df94f0b2ea46e320b.zip |
console:
* lines with leading space are ommitted from history
* exit processed even with whitespace around
* all whitespace lines (not only empty ones) are ignored
add 7 missing commands to admin api autocomplete
registrar: methods now return proper error if reg addresses are not set. fixes #1457
rpc/console: fix personal.newAccount() regression. Now all comms accept interactive password
registrar: add registrar tests for errors
crypto: catch AES decryption error on presale wallet import + fix error msg format. fixes #1580
CLI: improve error message when starting a second instance of geth. fixes #1564
cli/accounts: unlock multiple accounts. fixes #1785
* make unlocking multiple accounts work with inline <() fd
* passwdfile now correctly read only once
* improve logs
* fix CLI help text for unlocking
fix regression with docRoot / admin API
* docRoot/jspath passed to rpc/api ParseApis, which passes onto adminApi
* docRoot field for JS console in order to pass when RPC is (re)started
* improve flag desc for jspath
common/docserver: catch http errors from response
fix rpc/api tests
common/natspec: fix end to end test (skipped because takes 8s)
registrar: fix major regression:
* deploy registrars on frontier
* register HashsReg and UrlHint in GlobalRegistrar.
* set all 3 contract addresses in code
* zero out addresses first in tests
Diffstat (limited to 'common')
-rw-r--r-- | common/docserver/docserver.go | 6 | ||||
-rw-r--r-- | common/natspec/natspec_e2e_test.go | 117 | ||||
-rw-r--r-- | common/registrar/registrar.go | 52 | ||||
-rw-r--r-- | common/registrar/registrar_test.go | 62 |
4 files changed, 166 insertions, 71 deletions
diff --git a/common/docserver/docserver.go b/common/docserver/docserver.go index dac542ba7..cfc4e3b26 100644 --- a/common/docserver/docserver.go +++ b/common/docserver/docserver.go @@ -95,14 +95,20 @@ func (self *DocServer) Get(uri, path string) (content []byte, err error) { resp.Body.Close() } }() + if err != nil { return } + content, err = ioutil.ReadAll(resp.Body) if err != nil { return } + if resp.StatusCode/100 != 2 { + return content, fmt.Errorf("HTTP error: %s", resp.Status) + } + if path != "" { var abspath string abspath, err = filepath.Abs(path) diff --git a/common/natspec/natspec_e2e_test.go b/common/natspec/natspec_e2e_test.go index 02c2014ba..4149314c3 100644 --- a/common/natspec/natspec_e2e_test.go +++ b/common/natspec/natspec_e2e_test.go @@ -21,8 +21,8 @@ import ( "io/ioutil" "math/big" "os" + "path/filepath" "runtime" - "strings" "testing" "time" @@ -38,7 +38,9 @@ import ( ) const ( + testAddress = "0x8605cdbbdb6d264aa742e77020dcbc58fcdce182" testBalance = "10000000000000000000" + testKey = "e6fab74a43941f82d89cb7faa408e227cdad3153c4720e540e855c19b15e6674" testFileName = "long_file_name_for_testing_registration_of_URLs_longer_than_32_bytes.content" @@ -48,7 +50,7 @@ const ( testExpNotice2 = `About to submit transaction (NatSpec notice error: abi key does not match any method): {"params":[{"to":"%s","data": "0x31e12c20"}]}` - testExpNotice3 = `About to submit transaction (no NatSpec info found for contract: content hash not found for '0x1392c62d05b2d149e22a339c531157ae06b44d39a674cce500064b12b9aeb019'): {"params":[{"to":"%s","data": "0x300a3bbfb3a2dea218de5d8bbe6c4645aadbf67b5ab00ecb1a9ec95dbdad6a0eed3e41a7000000000000000000000000000000000000000000000000000000000000000000000000000000000000000066696c653a2f2f2f746573742e636f6e74656e74"}]}` + testExpNotice3 = `About to submit transaction (no NatSpec info found for contract: HashToHash: content hash not found for '0x1392c62d05b2d149e22a339c531157ae06b44d39a674cce500064b12b9aeb019'): {"params":[{"to":"%s","data": "0x300a3bbfb3a2dea218de5d8bbe6c4645aadbf67b5ab00ecb1a9ec95dbdad6a0eed3e41a7000000000000000000000000000000000000000000000000000000000000000000000000000000000000000066696c653a2f2f2f746573742e636f6e74656e74"}]}` ) const ( @@ -100,6 +102,10 @@ type testFrontend struct { wantNatSpec bool } +func (self *testFrontend) AskPassword() (string, bool) { + return "", true +} + func (self *testFrontend) UnlockAccount(acc []byte) bool { self.ethereum.AccountManager().Unlock(common.BytesToAddress(acc), "password") return true @@ -115,42 +121,42 @@ func (self *testFrontend) ConfirmTransaction(tx string) bool { func testEth(t *testing.T) (ethereum *eth.Ethereum, err error) { - os.RemoveAll("/tmp/eth-natspec/") - - err = os.MkdirAll("/tmp/eth-natspec/keystore", os.ModePerm) + tmp, err := ioutil.TempDir("", "natspec-test") if err != nil { - panic(err) + t.Fatal(err) } - - // create a testAddress - ks := crypto.NewKeyStorePassphrase("/tmp/eth-natspec/keystore") + db, _ := ethdb.NewMemDatabase() + addr := common.HexToAddress(testAddress) + core.WriteGenesisBlockForTesting(db, core.GenesisAccount{addr, common.String2Big(testBalance)}) + ks := crypto.NewKeyStorePassphrase(filepath.Join(tmp, "keystore")) am := accounts.NewManager(ks) - testAccount, err := am.NewAccount("password") + keyb, err := crypto.HexToECDSA(testKey) if err != nil { - panic(err) + t.Fatal(err) + } + key := crypto.NewKeyFromECDSA(keyb) + err = ks.StoreKey(key, "") + if err != nil { + t.Fatal(err) } - testAddress := strings.TrimPrefix(testAccount.Address.Hex(), "0x") - - db, _ := ethdb.NewMemDatabase() - // set up mock genesis with balance on the testAddress - core.WriteGenesisBlockForTesting(db, core.GenesisAccount{common.HexToAddress(testAddress), common.String2Big(testBalance)}) - - // only use minimalistic stack with no networking - ethereum, err = eth.New(ð.Config{ - DataDir: "/tmp/eth-natspec", - AccountManager: am, - MaxPeers: 0, - PowTest: true, - Etherbase: common.HexToAddress(testAddress), - NewDB: func(path string) (ethdb.Database, error) { return db, nil }, - }) - + err = am.Unlock(key.Address, "") if err != nil { - panic(err) + t.Fatal(err) } - return + // only use minimalistic stack with no networking + return eth.New(ð.Config{ + DataDir: tmp, + AccountManager: am, + Etherbase: common.HexToAddress(testAddress), + MaxPeers: 0, + PowTest: true, + NewDB: func(path string) (ethdb.Database, error) { return db, nil }, + GpoMinGasPrice: common.Big1, + GpobaseCorrectionFactor: 1, + GpoMaxGasPrice: common.Big1, + }) } func testInit(t *testing.T) (self *testFrontend) { @@ -174,36 +180,49 @@ func testInit(t *testing.T) (self *testFrontend) { // initialise the registry contracts reg := registrar.New(self.xeth) - var registrarTxhash, hashRegTxhash, urlHintTxhash string - registrarTxhash, err = reg.SetGlobalRegistrar("", addr) + registrar.GlobalRegistrarAddr = "0x0" + + var txG, txH, txU string + txG, err = reg.SetGlobalRegistrar("", addr) if err != nil { - t.Errorf("error creating GlobalRegistrar: %v", err) + t.Fatalf("error creating GlobalRegistrar: %v", err) } + if !processTxs(self, t, 1) { + t.Fatalf("error mining txs") + } + recG := self.xeth.GetTxReceipt(common.HexToHash(txG)) + if recG == nil { + t.Fatalf("blockchain error creating GlobalRegistrar") + } + registrar.GlobalRegistrarAddr = recG.ContractAddress.Hex() - hashRegTxhash, err = reg.SetHashReg("", addr) + txH, err = reg.SetHashReg("", addr) if err != nil { t.Errorf("error creating HashReg: %v", err) } - urlHintTxhash, err = reg.SetUrlHint("", addr) + if !processTxs(self, t, 1) { + t.Errorf("error mining txs") + } + recH := self.xeth.GetTxReceipt(common.HexToHash(txH)) + if recH == nil { + t.Fatalf("blockchain error creating HashReg") + } + registrar.HashRegAddr = recH.ContractAddress.Hex() + + txU, err = reg.SetUrlHint("", addr) if err != nil { t.Errorf("error creating UrlHint: %v", err) } - if !processTxs(self, t, 3) { + if !processTxs(self, t, 1) { t.Errorf("error mining txs") } - _ = registrarTxhash - _ = hashRegTxhash - _ = urlHintTxhash - - /* TODO: - * lookup receipt and contract addresses by tx hash - * name registration for HashReg and UrlHint addresses - * mine those transactions - * then set once more SetHashReg SetUrlHint - */ + recU := self.xeth.GetTxReceipt(common.HexToHash(txU)) + if recU == nil { + t.Fatalf("blockchain error creating UrlHint") + } + registrar.UrlHintAddr = recU.ContractAddress.Hex() return - } // end to end test @@ -215,7 +234,7 @@ func TestNatspecE2E(t *testing.T) { addr, _ := tf.ethereum.Etherbase() // create a contractInfo file (mock cloud-deployed contract metadocs) - // incidentally this is the info for the registry contract itself + // incidentally this is the info for the HashReg contract itself ioutil.WriteFile("/tmp/"+testFileName, []byte(testContractInfo), os.ModePerm) dochash := crypto.Sha3Hash([]byte(testContractInfo)) @@ -223,10 +242,6 @@ func TestNatspecE2E(t *testing.T) { codeb := tf.xeth.CodeAtBytes(registrar.HashRegAddr) codehash := crypto.Sha3Hash(codeb) - // use resolver to register codehash->dochash->url - // test if globalregistry works - // registrar.HashRefAddr = "0x0" - // registrar.UrlHintAddr = "0x0" reg := registrar.New(tf.xeth) _, err := reg.SetHashToHash(addr, codehash, dochash) if err != nil { diff --git a/common/registrar/registrar.go b/common/registrar/registrar.go index d891e161e..24e45edb3 100644 --- a/common/registrar/registrar.go +++ b/common/registrar/registrar.go @@ -48,17 +48,16 @@ The Registrar uses 3 contracts on the blockchain: These contracts are (currently) not included in the genesis block. Each Set<X> needs to be called once on each blockchain/network once. -Contract addresses need to be set (HashReg and UrlHint retrieved from the global -registrar the first time any Registrar method is called in a client session - -So the caller needs to make sure the relevant environment initialised the desired -contracts +Contract addresses need to be set the first time any Registrar method is called +in a client session. +This is done for frontier by default, otherwise the caller needs to make sure +the relevant environment initialised the desired contracts */ var ( - UrlHintAddr = "0x0" - HashRegAddr = "0x0" - GlobalRegistrarAddr = "0x0" - // GlobalRegistrarAddr = "0xc6d9d2cd449a754c494264e1809c50e34d64562b" + // GlobalRegistrarAddr = "0xc6d9d2cd449a754c494264e1809c50e34d64562b" // olympic + GlobalRegistrarAddr = "0x33990122638b9132ca29c723bdf037f1a891a70c" // frontier + HashRegAddr = "0x23bf622b5a65f6060d855fca401133ded3520620" // frontier + UrlHintAddr = "0x73ed5ef6c010727dfd2671dbb70faac19ec18626" // frontier zero = regexp.MustCompile("^(0x)?0*$") ) @@ -113,7 +112,7 @@ func (self *Registrar) SetGlobalRegistrar(namereg string, addr common.Address) ( GlobalRegistrarAddr = namereg return } - if GlobalRegistrarAddr == "0x0" || GlobalRegistrarAddr == "0x" { + if zero.MatchString(GlobalRegistrarAddr) { if (addr == common.Address{}) { err = fmt.Errorf("GlobalRegistrar address not found and sender for creation not given") return @@ -200,6 +199,9 @@ func (self *Registrar) SetUrlHint(urlhint string, addr common.Address) (txhash s // ReserveName(from, name) reserves name for the sender address in the globalRegistrar // the tx needs to be mined to take effect func (self *Registrar) ReserveName(address common.Address, name string) (txh string, err error) { + if zero.MatchString(GlobalRegistrarAddr) { + return "", fmt.Errorf("GlobalRegistrar address is not set") + } nameHex, extra := encodeName(name, 2) abi := reserveAbi + nameHex + extra glog.V(logger.Detail).Infof("Reserve data: %s", abi) @@ -215,6 +217,10 @@ func (self *Registrar) ReserveName(address common.Address, name string) (txh str // in the globalRegistrar using from as the sender of the transaction // the tx needs to be mined to take effect func (self *Registrar) SetAddressToName(from common.Address, name string, address common.Address) (txh string, err error) { + if zero.MatchString(GlobalRegistrarAddr) { + return "", fmt.Errorf("GlobalRegistrar address is not set") + } + nameHex, extra := encodeName(name, 6) addrHex := encodeAddress(address) @@ -231,6 +237,10 @@ func (self *Registrar) SetAddressToName(from common.Address, name string, addres // NameToAddr(from, name) queries the registrar for the address on name func (self *Registrar) NameToAddr(from common.Address, name string) (address common.Address, err error) { + if zero.MatchString(GlobalRegistrarAddr) { + return address, fmt.Errorf("GlobalRegistrar address is not set") + } + nameHex, extra := encodeName(name, 2) abi := resolveAbi + nameHex + extra glog.V(logger.Detail).Infof("NameToAddr data: %s", abi) @@ -249,6 +259,9 @@ func (self *Registrar) NameToAddr(from common.Address, name string) (address com // called as first step in the registration process on HashReg func (self *Registrar) SetOwner(address common.Address) (txh string, err error) { + if zero.MatchString(HashRegAddr) { + return "", fmt.Errorf("HashReg address is not set") + } return self.backend.Transact( address.Hex(), HashRegAddr, @@ -261,6 +274,10 @@ func (self *Registrar) SetOwner(address common.Address) (txh string, err error) // e.g., the contract Info combined Json Doc's ContentHash // to CodeHash of a contract or hash of a domain func (self *Registrar) SetHashToHash(address common.Address, codehash, dochash common.Hash) (txh string, err error) { + if zero.MatchString(HashRegAddr) { + return "", fmt.Errorf("HashReg address is not set") + } + _, err = self.SetOwner(address) if err != nil { return @@ -284,6 +301,10 @@ func (self *Registrar) SetHashToHash(address common.Address, codehash, dochash c // FIXME: silently doing nothing if sender is not the owner // note that with content addressed storage, this step is no longer necessary func (self *Registrar) SetUrlToHash(address common.Address, hash common.Hash, url string) (txh string, err error) { + if zero.MatchString(UrlHintAddr) { + return "", fmt.Errorf("UrlHint address is not set") + } + hashHex := common.Bytes2Hex(hash[:]) var urlHex string urlb := []byte(url) @@ -321,13 +342,17 @@ func (self *Registrar) SetUrlToHash(address common.Address, hash common.Hash, ur // resolution is costless non-transactional // implemented as direct retrieval from db func (self *Registrar) HashToHash(khash common.Hash) (chash common.Hash, err error) { + if zero.MatchString(HashRegAddr) { + return common.Hash{}, fmt.Errorf("HashReg address is not set") + } + // look up in hashReg at := HashRegAddr[2:] key := storageAddress(storageMapping(storageIdx2Addr(1), khash[:])) hash := self.backend.StorageAt(at, key) if hash == "0x0" || len(hash) < 3 || (hash == common.Hash{}.Hex()) { - err = fmt.Errorf("content hash not found for '%v'", khash.Hex()) + err = fmt.Errorf("HashToHash: content hash not found for '%v'", khash.Hex()) return } copy(chash[:], common.Hex2BytesFixed(hash[2:], 32)) @@ -339,6 +364,9 @@ func (self *Registrar) HashToHash(khash common.Hash) (chash common.Hash, err err // implemented as direct retrieval from db // if we use content addressed storage, this step is no longer necessary func (self *Registrar) HashToUrl(chash common.Hash) (uri string, err error) { + if zero.MatchString(UrlHintAddr) { + return "", fmt.Errorf("UrlHint address is not set") + } // look up in URL reg var str string = " " var idx uint32 @@ -358,7 +386,7 @@ func (self *Registrar) HashToUrl(chash common.Hash) (uri string, err error) { } if len(uri) == 0 { - err = fmt.Errorf("GetURLhint: URL hint not found for '%v'", chash.Hex()) + err = fmt.Errorf("HashToUrl: URL hint not found for '%v'", chash.Hex()) } return } diff --git a/common/registrar/registrar_test.go b/common/registrar/registrar_test.go index 63f283563..68ee65ab4 100644 --- a/common/registrar/registrar_test.go +++ b/common/registrar/registrar_test.go @@ -36,29 +36,31 @@ var ( ) func NewTestBackend() *testBackend { - HashRegAddr = common.BigToAddress(common.Big0).Hex() //[2:] - UrlHintAddr = common.BigToAddress(common.Big1).Hex() //[2:] self := &testBackend{} self.contracts = make(map[string](map[string]string)) + return self +} +func (self *testBackend) initHashReg() { self.contracts[HashRegAddr[2:]] = make(map[string]string) key := storageAddress(storageMapping(storageIdx2Addr(1), codehash[:])) self.contracts[HashRegAddr[2:]][key] = hash.Hex() +} +func (self *testBackend) initUrlHint() { self.contracts[UrlHintAddr[2:]] = make(map[string]string) mapaddr := storageMapping(storageIdx2Addr(1), hash[:]) - key = storageAddress(storageFixedArray(mapaddr, storageIdx2Addr(0))) + key := storageAddress(storageFixedArray(mapaddr, storageIdx2Addr(0))) self.contracts[UrlHintAddr[2:]][key] = common.ToHex([]byte(url)) key = storageAddress(storageFixedArray(mapaddr, storageIdx2Addr(1))) self.contracts[UrlHintAddr[2:]][key] = "0x0" - return self } func (self *testBackend) StorageAt(ca, sa string) (res string) { c := self.contracts[ca] if c == nil { - return + return "0x0" } res = c[sa] return @@ -84,9 +86,31 @@ func TestSetGlobalRegistrar(t *testing.T) { func TestHashToHash(t *testing.T) { b := NewTestBackend() res := New(b) - // res.SetHashReg() + HashRegAddr = "0x0" got, err := res.HashToHash(codehash) + if err == nil { + t.Errorf("expected error") + } else { + exp := "HashReg address is not set" + if err.Error() != exp { + t.Errorf("incorrect error, expected '%v', got '%v'", exp, err.Error()) + } + } + + HashRegAddr = common.BigToAddress(common.Big1).Hex() //[2:] + got, err = res.HashToHash(codehash) + if err == nil { + t.Errorf("expected error") + } else { + exp := "HashToHash: content hash not found for '" + codehash.Hex() + "'" + if err.Error() != exp { + t.Errorf("incorrect error, expected '%v', got '%v'", exp, err.Error()) + } + } + + b.initHashReg() + got, err = res.HashToHash(codehash) if err != nil { t.Errorf("expected no error, got %v", err) } else { @@ -99,11 +123,33 @@ func TestHashToHash(t *testing.T) { func TestHashToUrl(t *testing.T) { b := NewTestBackend() res := New(b) - // res.SetUrlHint() + UrlHintAddr = "0x0" got, err := res.HashToUrl(hash) + if err == nil { + t.Errorf("expected error") + } else { + exp := "UrlHint address is not set" + if err.Error() != exp { + t.Errorf("incorrect error, expected '%v', got '%v'", exp, err.Error()) + } + } + + UrlHintAddr = common.BigToAddress(common.Big2).Hex() //[2:] + got, err = res.HashToUrl(hash) + if err == nil { + t.Errorf("expected error") + } else { + exp := "HashToUrl: URL hint not found for '" + hash.Hex() + "'" + if err.Error() != exp { + t.Errorf("incorrect error, expected '%v', got '%v'", exp, err.Error()) + } + } + + b.initUrlHint() + got, err = res.HashToUrl(hash) if err != nil { - t.Errorf("expected error, got %v", err) + t.Errorf("expected no error, got %v", err) } else { if got != url { t.Errorf("incorrect result, expected '%v', got '%s'", url, got) |