func (self *StateObject) GetState(key common.Hash) common.Hash { strkey := key.Str() value, exists := self.storage[strkey] if !exists { value = self.getAddr(key) if (value != common.Hash{}) { self.storage[strkey] = value } } return value }
// HashToHash(key) resolves contenthash for key (a hash) using HashReg // resolution is costless non-transactional // implemented as direct retrieval from db func (self *Registrar) HashToHash(khash common.Hash) (chash common.Hash, err error) { // 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()) return } copy(chash[:], common.Hex2BytesFixed(hash[2:], 32)) return }
func (self *XEth) doSign(from common.Address, hash common.Hash, didUnlock bool) ([]byte, error) { sig, err := self.backend.AccountManager().Sign(accounts.Account{Address: from}, hash.Bytes()) if err == accounts.ErrLocked { if didUnlock { return nil, fmt.Errorf("signer account still locked after successful unlock") } if !self.frontend.UnlockAccount(from.Bytes()) { return nil, fmt.Errorf("could not unlock signer account") } // retry signing, the account should now be unlocked. return self.doSign(from, hash, true) } else if err != nil { return nil, err } return sig, nil }
// HashToUrl(contenthash) resolves the url for contenthash using UrlHint // resolution is costless non-transactional // 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) { // look up in URL reg 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(UrlHintAddr[2:], key) str = string(common.Hex2Bytes(hex[2:])) l := 0 for (l < len(str)) && (str[l] == 0) { l++ } str = str[l:] uri = uri + str idx++ } if len(uri) == 0 { err = fmt.Errorf("GetURLhint: URL hint not found for '%v'", chash.Hex()) } return }
// banBlocks retrieves a batch of blocks from a peer feeding us invalid hashes, // and bans the head of the retrieved batch. // // This method only fetches one single batch as the goal is not ban an entire // (potentially long) invalid chain - wasting a lot of time in the meanwhile -, // but rather to gradually build up a blacklist if the peer keeps reconnecting. func (d *Downloader) banBlocks(peerId string, head common.Hash) error { glog.V(logger.Debug).Infof("Banning a batch out of %d blocks from %s", d.queue.Pending(), peerId) // Ask the peer being banned for a batch of blocks from the banning point peer := d.peers.Peer(peerId) if peer == nil { return nil } request := d.queue.Reserve(peer, MaxBlockFetch) if request == nil { return nil } if err := peer.Fetch(request); err != nil { return err } // Wait a bit for the reply to arrive, and ban if done so timeout := time.After(blockHardTTL) for { select { case <-d.cancelCh: return errCancelBlockFetch case <-timeout: return errTimeout case <-d.hashCh: // Out of bounds hashes received, ignore them case blockPack := <-d.blockCh: blocks := blockPack.blocks // Short circuit if it's a stale cross check if len(blocks) == 1 { block := blocks[0] if _, ok := d.checks[block.Hash()]; ok { delete(d.checks, block.Hash()) break } } // Short circuit if it's not from the peer being banned if blockPack.peerId != peerId { break } // Short circuit if no blocks were returned if len(blocks) == 0 { return errors.New("no blocks returned to ban") } // Reconstruct the original chain order and ensure we're banning the correct blocks types.BlockBy(types.Number).Sort(blocks) if bytes.Compare(blocks[0].Hash().Bytes(), head.Bytes()) != 0 { return errors.New("head block not the banned one") } index := 0 for _, block := range blocks[1:] { if bytes.Compare(block.ParentHash().Bytes(), blocks[index].Hash().Bytes()) != 0 { break } index++ } // Ban the head hash and phase out any excess d.banned.Add(blocks[index].Hash()) for d.banned.Size() > maxBannedHashes { var evacuate common.Hash d.banned.Each(func(item interface{}) bool { // Skip any hard coded bans if core.BadHashes[item.(common.Hash)] { return true } evacuate = item.(common.Hash) return false }) d.banned.Remove(evacuate) } glog.V(logger.Debug).Infof("Banned %d blocks from: %s", index+1, peerId) return nil } } }
func (self *StateObject) SetState(k, value common.Hash) { self.storage[k.Str()] = value self.dirty = true }