add crosslink data structure and leveldb read/write

pull/1357/head
chao 5 years ago
parent 0af8cf0911
commit 5c512bef0e
  1. 20
      core/blockchain.go
  2. 10
      core/rawdb/accessors_chain.go
  3. 10
      core/rawdb/schema.go
  4. 1
      core/types/block.go
  5. 44
      core/types/crosslink.go

@ -1959,6 +1959,26 @@ func (bc *BlockChain) WriteEpochVdfBlockNum(epoch *big.Int, blockNum *big.Int) e
return nil return nil
} }
// WriteCrossLinks saves the hashes of crosslinks by shardID and blockNum combination key
func (bc *BlockChain) WriteCrossLinks(cls []types.CrossLink) error {
var err error
for _, cl := range cls {
err = rawdb.WriteCrossLinkShardBlock(bc.db, cl.ShardID(), cl.BlockNum(), cl.Bytes())
}
return err
}
// ReadCrossLink retrieves crosslink hash given shardID and blockNum
func (bc *BlockChain) ReadCrossLinkHash(shardID uint32, blockNum uint64) (common.Hash, error) {
h, err := rawdb.ReadCrossLinkShardBlock(bc.db, shardID, blockNum)
if err != nil {
return common.Hash{}, err
}
hash := common.Hash{}
hash.SetBytes(h)
return hash, nil
}
// IsSameLeaderAsPreviousBlock retrieves a block from the database by number, caching it // IsSameLeaderAsPreviousBlock retrieves a block from the database by number, caching it
func (bc *BlockChain) IsSameLeaderAsPreviousBlock(block *types.Block) bool { func (bc *BlockChain) IsSameLeaderAsPreviousBlock(block *types.Block) bool {
if block.NumberU64() == 0 { if block.NumberU64() == 0 {

@ -502,3 +502,13 @@ func ReadEpochVdfBlockNum(db DatabaseReader, epoch *big.Int) ([]byte, error) {
func WriteEpochVdfBlockNum(db DatabaseWriter, epoch *big.Int, data []byte) error { func WriteEpochVdfBlockNum(db DatabaseWriter, epoch *big.Int, data []byte) error {
return db.Put(epochVdfBlockNumberKey(epoch), data) return db.Put(epochVdfBlockNumberKey(epoch), data)
} }
// ReadCrossLinkShardBlock retrieves the blockHash given shardID and blockNum
func ReadCrossLinkShardBlock(db DatabaseReader, shardID uint32, blockNum uint64) ([]byte, error) {
return db.Get(crosslinkKey(shardID, blockNum))
}
// WriteCrossLinkShardBlock stores the blockHash given shardID and blockNum
func WriteCrossLinkShardBlock(db DatabaseWriter, shardID uint32, blockNum uint64, data []byte) error {
return db.Put(crosslinkKey(shardID, blockNum), data)
}

@ -60,6 +60,8 @@ var (
preimagePrefix = []byte("secure-key-") // preimagePrefix + hash -> preimage preimagePrefix = []byte("secure-key-") // preimagePrefix + hash -> preimage
configPrefix = []byte("ethereum-config-") // config prefix for the db configPrefix = []byte("ethereum-config-") // config prefix for the db
crosslinkPrefix = []byte("crosslink") // prefix for crosslink
// epochBlockNumberPrefix + epoch (big.Int.Bytes()) // epochBlockNumberPrefix + epoch (big.Int.Bytes())
// -> epoch block number (big.Int.Bytes()) // -> epoch block number (big.Int.Bytes())
epochBlockNumberPrefix = []byte("harmony-epoch-block-number-") epochBlockNumberPrefix = []byte("harmony-epoch-block-number-")
@ -162,3 +164,11 @@ func epochVrfBlockNumbersKey(epoch *big.Int) []byte {
func epochVdfBlockNumberKey(epoch *big.Int) []byte { func epochVdfBlockNumberKey(epoch *big.Int) []byte {
return append(epochVdfBlockNumberPrefix, epoch.Bytes()...) return append(epochVdfBlockNumberPrefix, epoch.Bytes()...)
} }
func crosslinkKey(shardID uint32, blockNum uint64) []byte {
sbKey := make([]byte, 12)
binary.BigEndian.PutUint32(sbKey, shardID)
binary.BigEndian.PutUint64(sbKey[4:], blockNum)
key := append(crosslinkPrefix, sbKey...)
return key
}

@ -93,6 +93,7 @@ type Header struct {
Vrf []byte `json:"vrf"` Vrf []byte `json:"vrf"`
Vdf []byte `json:"vdf"` Vdf []byte `json:"vdf"`
ShardState []byte `json:"shardState"` ShardState []byte `json:"shardState"`
CrossLink []byte `json:"crossLink"`
} }
// field type overrides for gencodec // field type overrides for gencodec

@ -0,0 +1,44 @@
package types
import (
"sort"
"github.com/ethereum/go-ethereum/common"
)
// CrossLink is only used on beacon chain to store the hash links from other shards
type CrossLink struct {
shardID uint32
blockNum uint64
hash common.Hash
}
// ShardID returns shardID
func (cl CrossLink) ShardID() uint32 {
return cl.shardID
}
// BlockNum returns blockNum
func (cl CrossLink) BlockNum() uint64 {
return cl.blockNum
}
// Hash returns hash
func (cl CrossLink) Hash() common.Hash {
return cl.hash
}
// Bytes returns bytes of the hash
func (cl CrossLink) Bytes() []byte {
return cl.hash[:]
}
// CrossLinks is a collection of cross links
type CrossLinks []CrossLink
// Sort crosslinks by shardID and then by blockNum
func (cls CrossLinks) Sort() {
sort.Slice(cls, func(i, j int) bool {
return cls[i].shardID < cls[j].shardID || (cls[i].shardID == cls[j].shardID && cls[i].blockNum < cls[j].blockNum)
})
}
Loading…
Cancel
Save