diff --git a/les/handler.go b/les/handler.go
index 9efe7d9e1213b9c5fa2443588074f739a82ea5bd..50c32fb95822b9de76a1600d8e524d26e9658048 100644
--- a/les/handler.go
+++ b/les/handler.go
@@ -72,7 +72,7 @@ type BlockChain interface {
 	GetHeaderByHash(hash common.Hash) *types.Header
 	CurrentHeader() *types.Header
 	GetTd(hash common.Hash, number uint64) *big.Int
-	State() (*state.StateDB, error)
+	StateCache() state.Database
 	InsertHeaderChain(chain []*types.Header, checkFreq int) (int, error)
 	Rollback(chain []common.Hash)
 	GetHeaderByNumber(number uint64) *types.Header
@@ -642,24 +642,33 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
 				if i != 0 && !task.waitOrStop() {
 					return
 				}
-				// Retrieve the requested state entry, stopping if enough was found
-				if number := rawdb.ReadHeaderNumber(pm.chainDb, req.BHash); number != nil {
-					if header := rawdb.ReadHeader(pm.chainDb, req.BHash, *number); header != nil {
-						statedb, err := pm.blockchain.State()
-						if err != nil {
-							continue
-						}
-						account, err := pm.getAccount(statedb, header.Root, common.BytesToHash(req.AccKey))
-						if err != nil {
-							continue
-						}
-						code, _ := statedb.Database().TrieDB().Node(common.BytesToHash(account.CodeHash))
+				// Look up the root hash belonging to the request
+				number := rawdb.ReadHeaderNumber(pm.chainDb, req.BHash)
+				if number == nil {
+					p.Log().Warn("Failed to retrieve block num for code", "hash", req.BHash)
+					continue
+				}
+				header := rawdb.ReadHeader(pm.chainDb, req.BHash, *number)
+				if header == nil {
+					p.Log().Warn("Failed to retrieve header for code", "block", *number, "hash", req.BHash)
+					continue
+				}
+				triedb := pm.blockchain.StateCache().TrieDB()
 
-						data = append(data, code)
-						if bytes += len(code); bytes >= softResponseLimit {
-							break
-						}
-					}
+				account, err := pm.getAccount(triedb, header.Root, common.BytesToHash(req.AccKey))
+				if err != nil {
+					p.Log().Warn("Failed to retrieve account for code", "block", header.Number, "hash", header.Hash(), "account", common.BytesToHash(req.AccKey), "err", err)
+					continue
+				}
+				code, err := triedb.Node(common.BytesToHash(account.CodeHash))
+				if err != nil {
+					p.Log().Warn("Failed to retrieve account code", "block", header.Number, "hash", header.Hash(), "account", common.BytesToHash(req.AccKey), "codehash", common.BytesToHash(account.CodeHash), "err", err)
+					continue
+				}
+				// Accumulate the code and abort if enough data was retrieved
+				data = append(data, code)
+				if bytes += len(code); bytes >= softResponseLimit {
+					break
 				}
 			}
 			sendResponse(req.ReqID, uint64(reqCnt), p.ReplyCode(req.ReqID, data), task.done())
@@ -779,34 +788,52 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
 				if i != 0 && !task.waitOrStop() {
 					return
 				}
-				// Retrieve the requested state entry, stopping if enough was found
-				if number := rawdb.ReadHeaderNumber(pm.chainDb, req.BHash); number != nil {
-					if header := rawdb.ReadHeader(pm.chainDb, req.BHash, *number); header != nil {
-						statedb, err := pm.blockchain.State()
-						if err != nil {
-							continue
-						}
-						var trie state.Trie
-						if len(req.AccKey) > 0 {
-							account, err := pm.getAccount(statedb, header.Root, common.BytesToHash(req.AccKey))
-							if err != nil {
-								continue
-							}
-							trie, _ = statedb.Database().OpenStorageTrie(common.BytesToHash(req.AccKey), account.Root)
-						} else {
-							trie, _ = statedb.Database().OpenTrie(header.Root)
-						}
-						if trie != nil {
-							var proof light.NodeList
-							trie.Prove(req.Key, 0, &proof)
+				// Look up the root hash belonging to the request
+				number := rawdb.ReadHeaderNumber(pm.chainDb, req.BHash)
+				if number == nil {
+					p.Log().Warn("Failed to retrieve block num for proof", "hash", req.BHash)
+					continue
+				}
+				header := rawdb.ReadHeader(pm.chainDb, req.BHash, *number)
+				if header == nil {
+					p.Log().Warn("Failed to retrieve header for proof", "block", *number, "hash", req.BHash)
+					continue
+				}
+				// Open the account or storage trie for the request
+				statedb := pm.blockchain.StateCache()
 
-							proofs = append(proofs, proof)
-							if bytes += proof.DataSize(); bytes >= softResponseLimit {
-								break
-							}
-						}
+				var trie state.Trie
+				switch len(req.AccKey) {
+				case 0:
+					// No account key specified, open an account trie
+					trie, err = statedb.OpenTrie(header.Root)
+					if trie == nil || err != nil {
+						p.Log().Warn("Failed to open storage trie for proof", "block", header.Number, "hash", header.Hash(), "root", header.Root, "err", err)
+						continue
+					}
+				default:
+					// Account key specified, open a storage trie
+					account, err := pm.getAccount(statedb.TrieDB(), header.Root, common.BytesToHash(req.AccKey))
+					if err != nil {
+						p.Log().Warn("Failed to retrieve account for proof", "block", header.Number, "hash", header.Hash(), "account", common.BytesToHash(req.AccKey), "err", err)
+						continue
+					}
+					trie, err = statedb.OpenStorageTrie(common.BytesToHash(req.AccKey), account.Root)
+					if trie == nil || err != nil {
+						p.Log().Warn("Failed to open storage trie for proof", "block", header.Number, "hash", header.Hash(), "account", common.BytesToHash(req.AccKey), "root", account.Root, "err", err)
+						continue
 					}
 				}
+				// Prove the user's request from the account or stroage trie
+				var proof light.NodeList
+				if err := trie.Prove(req.Key, 0, &proof); err != nil {
+					p.Log().Warn("Failed to prove state request", "block", header.Number, "hash", header.Hash(), "err", err)
+					continue
+				}
+				proofs = append(proofs, proof)
+				if bytes += proof.DataSize(); bytes >= softResponseLimit {
+					break
+				}
 			}
 			sendResponse(req.ReqID, uint64(reqCnt), p.ReplyProofs(req.ReqID, proofs), task.done())
 		}()
@@ -824,7 +851,6 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
 		// Gather state data until the fetch or network limits is reached
 		var (
 			lastBHash common.Hash
-			statedb   *state.StateDB
 			root      common.Hash
 		)
 		reqCnt := len(req.Reqs)
@@ -832,43 +858,60 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
 			return errResp(ErrRequestRejected, "")
 		}
 		go func() {
-
 			nodes := light.NewNodeSet()
 
 			for i, req := range req.Reqs {
 				if i != 0 && !task.waitOrStop() {
 					return
 				}
-				// Look up the state belonging to the request
-				if statedb == nil || req.BHash != lastBHash {
-					statedb, root, lastBHash = nil, common.Hash{}, req.BHash
-
-					if number := rawdb.ReadHeaderNumber(pm.chainDb, req.BHash); number != nil {
-						if header := rawdb.ReadHeader(pm.chainDb, req.BHash, *number); header != nil {
-							statedb, _ = pm.blockchain.State()
-							root = header.Root
-						}
+				// Look up the root hash belonging to the request
+				var (
+					number *uint64
+					header *types.Header
+					trie   state.Trie
+				)
+				if req.BHash != lastBHash {
+					root, lastBHash = common.Hash{}, req.BHash
+
+					if number = rawdb.ReadHeaderNumber(pm.chainDb, req.BHash); number == nil {
+						p.Log().Warn("Failed to retrieve block num for proof", "hash", req.BHash)
+						continue
 					}
+					if header = rawdb.ReadHeader(pm.chainDb, req.BHash, *number); header == nil {
+						p.Log().Warn("Failed to retrieve header for proof", "block", *number, "hash", req.BHash)
+						continue
+					}
+					root = header.Root
 				}
-				if statedb == nil {
-					continue
-				}
-				// Pull the account or storage trie of the request
-				var trie state.Trie
-				if len(req.AccKey) > 0 {
-					account, err := pm.getAccount(statedb, root, common.BytesToHash(req.AccKey))
+				// Open the account or storage trie for the request
+				statedb := pm.blockchain.StateCache()
+
+				switch len(req.AccKey) {
+				case 0:
+					// No account key specified, open an account trie
+					trie, err = statedb.OpenTrie(root)
+					if trie == nil || err != nil {
+						p.Log().Warn("Failed to open storage trie for proof", "block", header.Number, "hash", header.Hash(), "root", root, "err", err)
+						continue
+					}
+				default:
+					// Account key specified, open a storage trie
+					account, err := pm.getAccount(statedb.TrieDB(), root, common.BytesToHash(req.AccKey))
 					if err != nil {
+						p.Log().Warn("Failed to retrieve account for proof", "block", header.Number, "hash", header.Hash(), "account", common.BytesToHash(req.AccKey), "err", err)
+						continue
+					}
+					trie, err = statedb.OpenStorageTrie(common.BytesToHash(req.AccKey), account.Root)
+					if trie == nil || err != nil {
+						p.Log().Warn("Failed to open storage trie for proof", "block", header.Number, "hash", header.Hash(), "account", common.BytesToHash(req.AccKey), "root", account.Root, "err", err)
 						continue
 					}
-					trie, _ = statedb.Database().OpenStorageTrie(common.BytesToHash(req.AccKey), account.Root)
-				} else {
-					trie, _ = statedb.Database().OpenTrie(root)
 				}
-				if trie == nil {
+				// Prove the user's request from the account or stroage trie
+				if err := trie.Prove(req.Key, req.FromLevel, nodes); err != nil {
+					p.Log().Warn("Failed to prove state request", "block", header.Number, "hash", header.Hash(), "err", err)
 					continue
 				}
-				// Prove the user's request from the account or stroage trie
-				trie.Prove(req.Key, req.FromLevel, nodes)
 				if nodes.DataSize() >= softResponseLimit {
 					break
 				}
@@ -1190,8 +1233,8 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
 }
 
 // getAccount retrieves an account from the state based at root.
-func (pm *ProtocolManager) getAccount(statedb *state.StateDB, root, hash common.Hash) (state.Account, error) {
-	trie, err := trie.New(root, statedb.Database().TrieDB())
+func (pm *ProtocolManager) getAccount(triedb *trie.Database, root, hash common.Hash) (state.Account, error) {
+	trie, err := trie.New(root, triedb)
 	if err != nil {
 		return state.Account{}, err
 	}
diff --git a/light/lightchain.go b/light/lightchain.go
index fb5f8ead25ab54062a2722b3476a52f5feddcef0..38f1f634180b5284603b46d3c9de0b53c8412668 100644
--- a/light/lightchain.go
+++ b/light/lightchain.go
@@ -211,9 +211,8 @@ func (lc *LightChain) Genesis() *types.Block {
 	return lc.genesisBlock
 }
 
-// State returns a new mutable state based on the current HEAD block.
-func (lc *LightChain) State() (*state.StateDB, error) {
-	return nil, errors.New("not implemented, needs client/server interface split")
+func (lc *LightChain) StateCache() state.Database {
+	panic("not implemented")
 }
 
 // GetBody retrieves a block body (transactions and uncles) from the database