以太坊的存储层技术分析之二:以太坊和LevelDB的接口

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wxid2798226/article/details/83689579

LevelDB用户接口非常简单,主要就是Put(k,v),Get(k),Delete(k)。以太坊封装了LevelDB接口,见如下类详细代码:

---------------------------------------------------------------------------------------------

Go版本以太坊客户端:

github.com/ethereum/go-ethereum/ethdb/database.go

接口函数定义:

type LDBDatabase struct {

fn string      // filename for reporting

db *leveldb.DB // LevelDB instance

getTimer       gometrics.Timer // Timer for measuring the database get request counts and latencies

putTimer       gometrics.Timer // Timer for measuring the database put request counts and latencies

delTimer       gometrics.Timer // Timer for measuring the database delete request

missMeter      gometrics.Meter // Meter for measuring the missed database get requests

readMeter      gometrics.Meter // Meter for measuring the database get request data usage

writeMeter     gometrics.Meter // Meter for measuring the database put request data usage

compTimeMeter  gometrics.Meter // Meter for measuring the total time spent in database compaction

compReadMeter  gometrics.Meter // Meter for measuring the data read during compaction

compWriteMeter gometrics.Meter // Meter for measuring the data written during compaction

quitLock sync.Mutex      // Mutex protecting the quit channel access

quitChan chan chan error // Quit channel to stop the metrics collection before closing the database

}

func NewLDBDatabase(file string, cache int, handles int) (*LDBDatabase, error)

func (self *LDBDatabase) Put(key []byte, value []byte) error

func (self *LDBDatabase) Get(key []byte) ([]byte, error)

func (self *LDBDatabase) Delete(key []byte) error

func (db *LDBDatabase) NewBatch() Batch

func (self *LDBDatabase) Close()

---------------------------------------------------------------------------------------------

Java版本以太坊客户端:

org.ethereum.datasource.leveldb.LevelDbDataSource.java

接口函数定义:

String name;
DB db;
boolean alive;

// The native LevelDB insert/update/delete are normally thread-safe
// However close operation is not thread-safe and may lead to a native crash when accessing a closed DB.
// This ReadWriteLock still permits concurrent execution of insert/delete/update operations however blocks them on init/close/delete operations
private ReadWriteLock resetDbLock = new ReentrantReadWriteLock();

public boolean isAlive()

public void destroyDB(File fileLocation)

public byte[] get(byte[] key)

public void put(byte[] key, byte[] value)

public void delete(byte[] key)

public void updateBatch(Map<byte[], byte[]> rows)

public void close()

---------------------------------------------------------------------------------------------

以太坊客户端go语言实现的版本,和java语言实现的版本,在关键默认参数上是有区别的,见如下:

表1:Java版本和Go版本关键数据库参数差异

不仅关键数据库参数有差异,java版本和go版本调用LevelDB后数据存放的目录也是不同的。以太坊的存储层存储着两类相对独立但又有联系的数据:区块链数据库(chainDB)和账户状态数据库(stateDB)。其中,go版本将区块链数据库和账户状态数据库都存放在.ethereum目录下;而java版本将两者分开存放,分别放在block目录下和state目录下。

区块链数据库是一个区块编号和区块内容对应关系的数据库;而账户状态数据库是一个维护链中所有账户地址和其状态对应关系的数据库 , 以账户地址为key,以账户状态(包含nonce,余额,storageRoot,codeHash,见黄皮书4.1)为value。账户状态维护的是账户余额变动历史和合约账户执行历史,每次余额变动或合约代码被执行,都会生成一条记录,并被记录。所有账户状态数据库的查询,以账户地址为查询输入,而所有区块链上的查询,以区块编号等作为查询输入。技术上,可以理解为按照模块垂直划分成2个数据库实例。业务上,可以理解为交易流水账一个数据库实例,账户分户账一个数据库实例。

另外,以太坊还维护了一个节点信息的数据库,go版本的该数据库在nodes目录下,java版本的数据库在peers目录下,该部分是动态组网时所用,不是区块链本身内容。
 

猜你喜欢

转载自blog.csdn.net/wxid2798226/article/details/83689579
今日推荐