diff options
-rw-r--r-- | common/natspec/natspec_e2e_test.go | 28 | ||||
-rw-r--r-- | common/resolver/contracts.go | 8 | ||||
-rw-r--r-- | common/resolver/resolver.go | 56 |
3 files changed, 70 insertions, 22 deletions
diff --git a/common/natspec/natspec_e2e_test.go b/common/natspec/natspec_e2e_test.go index e8dba7d16..4e0f656f3 100644 --- a/common/natspec/natspec_e2e_test.go +++ b/common/natspec/natspec_e2e_test.go @@ -38,10 +38,12 @@ const ( testBalance = "1000000000000" ) +const testFileName = "long_file_name_for_testing_registration_of_URLs_longer_than_32_bytes.content" + const testNotice = "Register key `utils.toHex(_key)` <- content `utils.toHex(_content)`" const testExpNotice = "Register key 0xadd1a7d961cff0242089674ec2ef6fca671ab15e1fe80e38859fc815b98d88ab <- content 0xc00d5bcc872e17813df6ec5c646bb281a6e2d3b454c2c400c78192adf3344af9" const testExpNotice2 = `About to submit transaction (NatSpec notice error "abi key %!x(MISSING) does not match any method %!v(MISSING)"): {"id":6,"jsonrpc":"2.0","method":"eth_transact","params":[{"from":"0xe273f01c99144c438695e10f24926dc1f9fbf62d","to":"0xb737b91f8e95cf756766fc7c62c9a8ff58470381","value":"100000000000","gas":"100000","gasPrice":"100000","data":"0x31e12c20"}]}` -const testExpNotice3 = `About to submit transaction (no NatSpec info found for contract): {"id":6,"jsonrpc":"2.0","method":"eth_transact","params":[{"from":"0xe273f01c99144c438695e10f24926dc1f9fbf62d","to":"0x8b839ad85686967a4f418eccc81962eaee314ac3","value":"100000000000","gas":"100000","gasPrice":"100000","data":"0xd66d6c10c00d5bcc872e17813df6ec5c646bb281a6e2d3b454c2c400c78192adf3344af900000000000000000000000066696c653a2f2f2f746573742e636f6e74656e74"}]}` +const testExpNotice3 = `About to submit transaction (no NatSpec info found for contract): {"id":6,"jsonrpc":"2.0","method":"eth_transact","params":[{"from":"0xe273f01c99144c438695e10f24926dc1f9fbf62d","to":"0x8b839ad85686967a4f418eccc81962eaee314ac3","value":"100000000000","gas":"100000","gasPrice":"100000","data":"0x300a3bbfc00d5bcc872e17813df6ec5c646bb281a6e2d3b454c2c400c78192adf3344af900000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000"}]}` const testUserDoc = ` { @@ -244,8 +246,24 @@ func (self *testFrontend) applyTxs() { func (self *testFrontend) registerURL(hash common.Hash, url string) { hashHex := common.Bytes2Hex(hash[:]) - urlHex := common.Bytes2Hex([]byte(url)) - self.insertTx(self.coinbase, resolver.URLHintContractAddress, "register(uint256,uint256)", []string{hashHex, urlHex}) + urlBytes := []byte(url) + var bb bool = true + var cnt byte + for bb { + bb = len(urlBytes) > 0 + urlb := urlBytes + if len(urlb) > 32 { + urlb = urlb[:32] + } + urlHex := common.Bytes2Hex(urlb) + self.insertTx(self.coinbase, resolver.URLHintContractAddress, "register(uint256,uint8,uint256)", []string{hashHex, common.Bytes2Hex([]byte{cnt}), urlHex}) + if len(urlBytes) > 32 { + urlBytes = urlBytes[32:] + } else { + urlBytes = nil + } + cnt++ + } } func (self *testFrontend) setOwner() { @@ -280,7 +298,7 @@ func TestNatspecE2E(t *testing.T) { t.Logf("HashReg contract registered at %v", resolver.HashRegContractAddress) tf.applyTxs() - ioutil.WriteFile("/tmp/test.content", []byte(testDocs), os.ModePerm) + ioutil.WriteFile("/tmp/"+testFileName, []byte(testDocs), os.ModePerm) dochash := common.BytesToHash(crypto.Sha3([]byte(testDocs))) codehex := tf.xeth.CodeAt(resolver.HashRegContractAddress) @@ -288,7 +306,7 @@ func TestNatspecE2E(t *testing.T) { tf.setOwner() tf.registerNatSpec(codehash, dochash) - tf.registerURL(dochash, "file:///test.content") + tf.registerURL(dochash, "file:///"+testFileName) tf.applyTxs() chash, err := tf.testResolver().KeyToContentHash(codehash) diff --git a/common/resolver/contracts.go b/common/resolver/contracts.go index ed7d648d6..4aad95e43 100644 --- a/common/resolver/contracts.go +++ b/common/resolver/contracts.go @@ -1,17 +1,17 @@ package resolver const ( // built-in contracts address and code - ContractCodeURLhint = "0x60b180600c6000396000f30060003560e060020a90048063d66d6c1014601557005b60216004356024356027565b60006000f35b6000600083815260200190815260200160002054600160a060020a0316600014806075575033600160a060020a03166000600084815260200190815260200160002054600160a060020a0316145b607c5760ad565b3360006000848152602001908152602001600020819055508060016000848152602001908152602001600020819055505b505056" + ContractCodeURLhint = "0x60c180600c6000396000f30060003560e060020a90048063300a3bbf14601557005b6024600435602435604435602a565b60006000f35b6000600084815260200190815260200160002054600160a060020a0316600014806078575033600160a060020a03166000600085815260200190815260200160002054600160a060020a0316145b607f5760bc565b336000600085815260200190815260200160002081905550806001600085815260200190815260200160002083610100811060b657005b01819055505b50505056" /* contract URLhint { - function register(uint256 _hash, uint256 _url) { + function register(uint256 _hash, uint8 idx, uint256 _url) { if (owner[_hash] == 0 || owner[_hash] == msg.sender) { owner[_hash] = msg.sender; - url[_hash] = _url; + url[_hash][idx] = _url; } } mapping (uint256 => address) owner; - mapping (uint256 => uint256) url; + mapping (uint256 => uint256[256]) url; } */ diff --git a/common/resolver/resolver.go b/common/resolver/resolver.go index 45afb2971..35f765349 100644 --- a/common/resolver/resolver.go +++ b/common/resolver/resolver.go @@ -52,7 +52,7 @@ func New(eth Backend, uhca, nrca string) *Resolver { func (self *Resolver) KeyToContentHash(khash common.Hash) (chash common.Hash, err error) { // look up in hashReg - key := storageAddress(1, khash[:]) + key := storageAddress(storageMapping(storageIdx2Addr(1), khash[:])) hash := self.backend.StorageAt("0x"+self.hashRegContractAddress, key) if hash == "0x0" || len(hash) < 3 { @@ -66,16 +66,23 @@ func (self *Resolver) KeyToContentHash(khash common.Hash) (chash common.Hash, er func (self *Resolver) ContentHashToUrl(chash common.Hash) (uri string, err error) { // look up in URL reg - key := storageAddress(1, chash[:]) - hex := self.backend.StorageAt("0x"+self.urlHintContractAddress, key) - uri = string(common.Hex2Bytes(hex[2:])) - l := len(uri) - for (l > 0) && (uri[l-1] == 0) { - l-- + var str string = " " + var idx uint32 + for len(str) > 0 { + mapaddr := storageMapping(storageIdx2Addr(1), chash[:]) + key := storageAddress(storageFixedArray(mapaddr, storageIdx2Addr(idx))) + hex := self.backend.StorageAt("0x"+self.urlHintContractAddress, key) + str = string(common.Hex2Bytes(hex[2:])) + l := len(str) + for (l > 0) && (str[l-1] == 0) { + l-- + } + str = str[:l] + uri = uri + str + idx++ } - uri = uri[:l] - if l == 0 { + if len(uri) == 0 { err = fmt.Errorf("GetURLhint: URL hint not found") } return @@ -91,10 +98,33 @@ func (self *Resolver) KeyToUrl(key common.Hash) (uri string, hash common.Hash, e return } -func storageAddress(varidx uint32, key []byte) string { +func storageIdx2Addr(varidx uint32) []byte { + data := make([]byte, 32) + binary.BigEndian.PutUint32(data[28:32], varidx) + return data +} + +func storageMapping(addr, key []byte) []byte { data := make([]byte, 64) - binary.BigEndian.PutUint32(data[60:64], varidx) copy(data[0:32], key[0:32]) - //fmt.Printf("%x %v\n", key, common.Bytes2Hex(crypto.Sha3(data))) - return "0x" + common.Bytes2Hex(crypto.Sha3(data)) + copy(data[32:64], addr[0:32]) + return crypto.Sha3(data) +} + +func storageFixedArray(addr, idx []byte) []byte { + var carry byte + for i := 31; i >= 0; i-- { + var b byte = addr[i] + idx[i] + carry + if b < addr[i] { + carry = 1 + } else { + carry = 0 + } + addr[i] = b + } + return addr +} + +func storageAddress(addr []byte) string { + return "0x" + common.Bytes2Hex(addr) } |