aboutsummaryrefslogtreecommitdiffstats
path: root/light/nodeset.go
diff options
context:
space:
mode:
authorFelföldi Zsolt <zsfelfoldi@gmail.com>2017-10-24 21:19:09 +0800
committerFelix Lange <fjl@users.noreply.github.com>2017-10-24 21:19:09 +0800
commitca376ead88a5a26626a90abdb62f4de7f6313822 (patch)
tree71d11e3b6cd40d2bf29033b7e23d30d04e086558 /light/nodeset.go
parent6d6a5a93370371a33fb815d7ae47b60c7021c86a (diff)
downloadgo-tangerine-ca376ead88a5a26626a90abdb62f4de7f6313822.tar
go-tangerine-ca376ead88a5a26626a90abdb62f4de7f6313822.tar.gz
go-tangerine-ca376ead88a5a26626a90abdb62f4de7f6313822.tar.bz2
go-tangerine-ca376ead88a5a26626a90abdb62f4de7f6313822.tar.lz
go-tangerine-ca376ead88a5a26626a90abdb62f4de7f6313822.tar.xz
go-tangerine-ca376ead88a5a26626a90abdb62f4de7f6313822.tar.zst
go-tangerine-ca376ead88a5a26626a90abdb62f4de7f6313822.zip
les, light: LES/2 protocol version (#14970)
This PR implements the new LES protocol version extensions: * new and more efficient Merkle proofs reply format (when replying to a multiple Merkle proofs request, we just send a single set of trie nodes containing all necessary nodes) * BBT (BloomBitsTrie) works similarly to the existing CHT and contains the bloombits search data to speed up log searches * GetTxStatusMsg returns the inclusion position or the pending/queued/unknown state of a transaction referenced by hash * an optional signature of new block data (number/hash/td) can be included in AnnounceMsg to provide an option for "very light clients" (mobile/embedded devices) to skip expensive Ethash check and accept multiple signatures of somewhat trusted servers (still a lot better than trusting a single server completely and retrieving everything through RPC). The new client mode is not implemented in this PR, just the protocol extension.
Diffstat (limited to 'light/nodeset.go')
-rw-r--r--light/nodeset.go141
1 files changed, 141 insertions, 0 deletions
diff --git a/light/nodeset.go b/light/nodeset.go
new file mode 100644
index 000000000..c530a4fbe
--- /dev/null
+++ b/light/nodeset.go
@@ -0,0 +1,141 @@
+// Copyright 2014 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
+
+package light
+
+import (
+ "errors"
+ "sync"
+
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/crypto"
+ "github.com/ethereum/go-ethereum/rlp"
+ "github.com/ethereum/go-ethereum/trie"
+)
+
+// NodeSet stores a set of trie nodes. It implements trie.Database and can also
+// act as a cache for another trie.Database.
+type NodeSet struct {
+ db map[string][]byte
+ dataSize int
+ lock sync.RWMutex
+}
+
+// NewNodeSet creates an empty node set
+func NewNodeSet() *NodeSet {
+ return &NodeSet{
+ db: make(map[string][]byte),
+ }
+}
+
+// Put stores a new node in the set
+func (db *NodeSet) Put(key []byte, value []byte) error {
+ db.lock.Lock()
+ defer db.lock.Unlock()
+
+ if _, ok := db.db[string(key)]; !ok {
+ db.db[string(key)] = common.CopyBytes(value)
+ db.dataSize += len(value)
+ }
+ return nil
+}
+
+// Get returns a stored node
+func (db *NodeSet) Get(key []byte) ([]byte, error) {
+ db.lock.RLock()
+ defer db.lock.RUnlock()
+
+ if entry, ok := db.db[string(key)]; ok {
+ return entry, nil
+ }
+ return nil, errors.New("not found")
+}
+
+// Has returns true if the node set contains the given key
+func (db *NodeSet) Has(key []byte) (bool, error) {
+ _, err := db.Get(key)
+ return err == nil, nil
+}
+
+// KeyCount returns the number of nodes in the set
+func (db *NodeSet) KeyCount() int {
+ db.lock.RLock()
+ defer db.lock.RUnlock()
+
+ return len(db.db)
+}
+
+// DataSize returns the aggregated data size of nodes in the set
+func (db *NodeSet) DataSize() int {
+ db.lock.RLock()
+ defer db.lock.RUnlock()
+
+ return db.dataSize
+}
+
+// NodeList converts the node set to a NodeList
+func (db *NodeSet) NodeList() NodeList {
+ db.lock.RLock()
+ defer db.lock.RUnlock()
+
+ var values NodeList
+ for _, value := range db.db {
+ values = append(values, value)
+ }
+ return values
+}
+
+// Store writes the contents of the set to the given database
+func (db *NodeSet) Store(target trie.Database) {
+ db.lock.RLock()
+ defer db.lock.RUnlock()
+
+ for key, value := range db.db {
+ target.Put([]byte(key), value)
+ }
+}
+
+// NodeList stores an ordered list of trie nodes. It implements trie.DatabaseWriter.
+type NodeList []rlp.RawValue
+
+// Store writes the contents of the list to the given database
+func (n NodeList) Store(db trie.Database) {
+ for _, node := range n {
+ db.Put(crypto.Keccak256(node), node)
+ }
+}
+
+// NodeSet converts the node list to a NodeSet
+func (n NodeList) NodeSet() *NodeSet {
+ db := NewNodeSet()
+ n.Store(db)
+ return db
+}
+
+// Put stores a new node at the end of the list
+func (n *NodeList) Put(key []byte, value []byte) error {
+ *n = append(*n, value)
+ return nil
+}
+
+// DataSize returns the aggregated data size of nodes in the list
+func (n NodeList) DataSize() int {
+ var size int
+ for _, node := range n {
+ size += len(node)
+ }
+ return size
+}