Go-ethereum Source Analysis: Block storage

Source: Internet
Author: User
Tags data structures hash

Data such as chunks and transactions are ultimately stored in the LEVELDB database, and this article describes the storage formats for chunks and transactions in Leveldb. All code related to chunk storage and reading is encapsulated in Core/database_util.go, which allows you to figure out how chunks, transactions, and other data structures are stored in the database.

Chunk storage

LEVELDB is a key-value database, and all data is stored as key-value pairs. Key is generally related to hash, and value is generally the RLP encoding of the data structure to be stored. Chunk storage is stored separately from chunk size and block body.

The storage format for the chunk header is:

Headerprefix + num (UInt64 big endian) + hash Rlpencode (header)

Where key is composed of chunk number (UInt64 big-endian format), chunk hash, and a prefix, value is the RLP code of the chunk header.

The storage format for block bodies is:

Bodyprefix + num (UInt64 big endian) + Hash-rlpencode (block body)

Where key is composed of chunk number (UInt64 big-endian format), chunk hash, and a prefix, value is the RLP encoding of the block body.

The prefixes in key can be used to differentiate between types of data, and various prefixes are defined in Core/database_util.go:

Headerprefix        = []byte ("H")   //Headerprefix + num (UInt64 big endian) + hash header
Tdsuffix            = []byte ("T")   Headerprefix + num (UInt64 big endian) + hash + tdsuffix td
Numsuffix           = []byte ("n")   //Headerprefix +  Num (UInt64 big endian) + Numsuffix, hash
blockhashprefix     = []byte ("H")   //Blockhashprefix + hash Num (UInt64 big endian)
bodyprefix          = []byte ("B")   //Bodyprefix + num (UInt64 big endian) + hash bloc K Body

Where Headerprefix defines the prefix for the chunk header to H,bodyprefix defines the chunk body prefixed with B.

Here is the function that stores the chunk header:

Writeheader serializes a block header into the database.
Func writeheader (db ethdb. Database, Header *types. Header) Error {
    data, err: = RLP. Encodetobytes (header)
    if err! = Nil {
        return err
    }
    Hash: = header. Hash (). Bytes ()
    num: = header. Number.uint64 ()
    encnum: = Encodeblocknumber (num)
    key: = Append (Blockhashprefix, hash ...)
    If err: = db. Put (key, Encnum); Err! = Nil {
        glog. Fatalf ("Failed to store hash to number mapping into database:%v", err)
    }
    key = Append (Append (Headerprefix, ENCN Um ...), hash ...)
    If err: = db. Put (key, data); Err! = Nil {
        glog. Fatalf ("failed to store header into database:%v", err)
    }
    glog. V (logger. Debug). Infof ("Stored header #%v [%x ...]", header. Number, Hash[:4])
    return nil
}

It first RLP the chunk header, encodeblocknumber the chunk number into the big-endian format, and then assembles the key. This first stores a chunk hash-> block number mapping to the database, and then writes the RLP encoding of the chunk header to the database.

Here is the function that stores the chunk body:

Writebody serializes the body of a block into the database.
Func writebody (db ethdb. Database, Hash common. Hash, number UInt64, body *types. Body) Error {
    data, err: = RLP. Encodetobytes (body)
    if err! = Nil {
        return err
    }
    return WRITEBODYRLP (db, hash, number, data)
}

WRITEBODYRLP writes a serialized body of a block into the database.
Func WRITEBODYRLP (db ethdb. Database, Hash common. Hash, number UInt64, RLP RLP. RawValue) Error {
    key: = Append (Append (Bodyprefix, encodeblocknumber (number) ...), hash. Bytes () ...)
    If err: = db. Put (key, RLP); Err! = Nil {
        glog. Fatalf ("Failed to store block body into database:%v", err)
    }
    glog. V (logger. Debug). Infof ("stored block body [%x ...]", hash. Bytes () [: 4])
    return nil
}

Writebody RLP code The chunk body first, and then calls WRITEBODYRLP to write the RLP encoding of the chunk body to the database. WRITEBODYRLP assembles the key according to the rules above, and then writes a record to the database.

The

also has a writeblock function that calls Writebody and writeheader to write chunks to the database, respectively. The GetHeader getbody getblock function is also used to read chunks from the database.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.