github.com/ethw3/go-ethereuma@v0.0.0-20221013053120-c14602a4c23c/ethdb/remotedb/remotedb.go (about) 1 // Copyright 2022 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 // Package remotedb implements the key-value database layer based on a remote geth 18 // node. Under the hood, it utilises the `debug_dbGet` method to implement a 19 // read-only database. 20 // There really are no guarantees in this database, since the local geth does not 21 // exclusive access, but it can be used for basic diagnostics of a remote node. 22 package remotedb 23 24 import ( 25 "errors" 26 "strings" 27 28 "github.com/ethw3/go-ethereuma/common/hexutil" 29 "github.com/ethw3/go-ethereuma/ethdb" 30 "github.com/ethw3/go-ethereuma/rpc" 31 ) 32 33 // Database is a key-value lookup for a remote database via debug_dbGet. 34 type Database struct { 35 remote *rpc.Client 36 } 37 38 func (db *Database) Has(key []byte) (bool, error) { 39 if _, err := db.Get(key); err != nil { 40 return false, nil 41 } 42 return true, nil 43 } 44 45 func (db *Database) Get(key []byte) ([]byte, error) { 46 var resp hexutil.Bytes 47 err := db.remote.Call(&resp, "debug_dbGet", hexutil.Bytes(key)) 48 if err != nil { 49 return nil, err 50 } 51 return resp, nil 52 } 53 54 func (db *Database) HasAncient(kind string, number uint64) (bool, error) { 55 if _, err := db.Ancient(kind, number); err != nil { 56 return false, nil 57 } 58 return true, nil 59 } 60 61 func (db *Database) Ancient(kind string, number uint64) ([]byte, error) { 62 var resp hexutil.Bytes 63 err := db.remote.Call(&resp, "debug_dbAncient", kind, number) 64 if err != nil { 65 return nil, err 66 } 67 return resp, nil 68 } 69 70 func (db *Database) AncientRange(kind string, start, count, maxBytes uint64) ([][]byte, error) { 71 panic("not supported") 72 } 73 74 func (db *Database) Ancients() (uint64, error) { 75 var resp uint64 76 err := db.remote.Call(&resp, "debug_dbAncients") 77 return resp, err 78 } 79 80 func (db *Database) Tail() (uint64, error) { 81 panic("not supported") 82 } 83 84 func (db *Database) AncientSize(kind string) (uint64, error) { 85 panic("not supported") 86 } 87 88 func (db *Database) ReadAncients(fn func(op ethdb.AncientReaderOp) error) (err error) { 89 return fn(db) 90 } 91 92 func (db *Database) Put(key []byte, value []byte) error { 93 panic("not supported") 94 } 95 96 func (db *Database) Delete(key []byte) error { 97 panic("not supported") 98 } 99 100 func (db *Database) ModifyAncients(f func(ethdb.AncientWriteOp) error) (int64, error) { 101 panic("not supported") 102 } 103 104 func (db *Database) TruncateHead(n uint64) error { 105 panic("not supported") 106 } 107 108 func (db *Database) TruncateTail(n uint64) error { 109 panic("not supported") 110 } 111 112 func (db *Database) Sync() error { 113 return nil 114 } 115 116 func (db *Database) MigrateTable(s string, f func([]byte) ([]byte, error)) error { 117 panic("not supported") 118 } 119 120 func (db *Database) NewBatch() ethdb.Batch { 121 panic("not supported") 122 } 123 124 func (db *Database) NewBatchWithSize(size int) ethdb.Batch { 125 panic("not supported") 126 } 127 128 func (db *Database) NewIterator(prefix []byte, start []byte) ethdb.Iterator { 129 panic("not supported") 130 } 131 132 func (db *Database) Stat(property string) (string, error) { 133 panic("not supported") 134 } 135 136 func (db *Database) AncientDatadir() (string, error) { 137 panic("not supported") 138 } 139 140 func (db *Database) Compact(start []byte, limit []byte) error { 141 return nil 142 } 143 144 func (db *Database) NewSnapshot() (ethdb.Snapshot, error) { 145 panic("not supported") 146 } 147 148 func (db *Database) Close() error { 149 db.remote.Close() 150 return nil 151 } 152 153 func dialRPC(endpoint string) (*rpc.Client, error) { 154 if endpoint == "" { 155 return nil, errors.New("endpoint must be specified") 156 } 157 if strings.HasPrefix(endpoint, "rpc:") || strings.HasPrefix(endpoint, "ipc:") { 158 // Backwards compatibility with geth < 1.5 which required 159 // these prefixes. 160 endpoint = endpoint[4:] 161 } 162 return rpc.Dial(endpoint) 163 } 164 165 func New(endpoint string) (ethdb.Database, error) { 166 client, err := dialRPC(endpoint) 167 if err != nil { 168 return nil, err 169 } 170 return &Database{ 171 remote: client, 172 }, nil 173 }