feat(*): construct interchain txs merkle tree

This commit is contained in:
zhourong 2020-05-26 14:15:20 +08:00
parent 5a866c23eb
commit c6e48f257d
9 changed files with 168 additions and 77 deletions

7
go.mod
View File

@ -3,6 +3,7 @@ module github.com/meshplus/bitxhub
require (
github.com/Rican7/retry v0.1.0
github.com/aristanetworks/goarista v0.0.0-20200310212843-2da4c1f5881b // indirect
github.com/cbergoon/merkletree v0.2.0
github.com/common-nighthawk/go-figure v0.0.0-20190529165535-67e0ed34491a
github.com/coreos/etcd v3.3.18+incompatible
github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f // indirect
@ -19,9 +20,9 @@ require (
github.com/hokaccha/go-prettyjson v0.0.0-20190818114111-108c894c2c0e
github.com/libp2p/go-libp2p-core v0.3.0
github.com/magiconair/properties v1.8.1
github.com/meshplus/bitxhub-core v0.1.0-rc1.0.20200509070216-b812d490a331
github.com/meshplus/bitxhub-kit v1.0.1-0.20200501052627-8bef1d2acc6e
github.com/meshplus/bitxhub-model v1.0.0-rc4.0.20200427024612-57b479c1d610
github.com/meshplus/bitxhub-core v0.1.0-rc1.0.20200526060151-b0efad4a2046
github.com/meshplus/bitxhub-kit v1.0.1-0.20200525060338-39d86f7542ae
github.com/meshplus/bitxhub-model v1.0.0-rc4.0.20200514093243-7e8ae60d1c19
github.com/mitchellh/go-homedir v1.1.0
github.com/multiformats/go-multiaddr v0.2.0
github.com/pkg/errors v0.9.1

23
go.sum
View File

@ -501,18 +501,26 @@ github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzp
github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/meshplus/bitxhub-core v0.1.0-rc1.0.20200509070216-b812d490a331 h1:1G3kkI8YYZTqj9QzfKy51SGgku5Oil2CQCJpdA3xQjI=
github.com/meshplus/bitxhub-core v0.1.0-rc1.0.20200509070216-b812d490a331/go.mod h1:0iCI1ACHiEaVpt3C68NcgDq47dH8DI5FI7Lh9eHQAiw=
github.com/meshplus/bitxhub-core v0.1.0-rc1.0.20200519073726-194263cfe6ab h1:g1QW8TgqmEu7bRFuinFcNurhuDOStBt/ZbRJhDFgHrk=
github.com/meshplus/bitxhub-core v0.1.0-rc1.0.20200519073726-194263cfe6ab/go.mod h1:JAxVCppTLwO6+NG6z0ycK0RuZZvNFavsx5vqrsV2ewM=
github.com/meshplus/bitxhub-core v0.1.0-rc1.0.20200525071523-662c6a8b75fa h1:TmMClDcWPfRGQNtTIMt9QdYgq5oJQRgf7uhBjyj82t0=
github.com/meshplus/bitxhub-core v0.1.0-rc1.0.20200525071523-662c6a8b75fa/go.mod h1:txnekA7OS4YIixuSCk62BFKkmlqMP2w4R6Em8AR04pg=
github.com/meshplus/bitxhub-core v0.1.0-rc1.0.20200526060151-b0efad4a2046 h1:0ZJsnB7alktEYU8XX7LH4h8umkrYA2n8CGPZVwzdjx8=
github.com/meshplus/bitxhub-core v0.1.0-rc1.0.20200526060151-b0efad4a2046/go.mod h1:txnekA7OS4YIixuSCk62BFKkmlqMP2w4R6Em8AR04pg=
github.com/meshplus/bitxhub-kit v1.0.0-rc1 h1:gNi8IFU5CMHT3KE2I4ACj5alMW9h/4cV8xOxn7wSmtA=
github.com/meshplus/bitxhub-kit v1.0.0-rc1/go.mod h1:ra/AhOkPvpElI+wXrB9G6DjdcrdxFU3vMwA5MYKr9D0=
github.com/meshplus/bitxhub-kit v1.0.1-0.20200429033154-8736253c8460 h1:bL+s+LBhGr4g+28DNtqyj4WoVkYdZ5CPoGjdF6Ll0sk=
github.com/meshplus/bitxhub-kit v1.0.1-0.20200429033154-8736253c8460/go.mod h1:7cWyhXWZfrQ3+EaxkRoXfuiG3Y5R9DXYJomeZKkETW8=
github.com/meshplus/bitxhub-kit v1.0.1-0.20200501052627-8bef1d2acc6e h1:venrZxmUu3Wjayb8yNr7+Gh0wyUGCE6f5I8JTePn4d0=
github.com/meshplus/bitxhub-kit v1.0.1-0.20200501052627-8bef1d2acc6e/go.mod h1:7cWyhXWZfrQ3+EaxkRoXfuiG3Y5R9DXYJomeZKkETW8=
github.com/meshplus/bitxhub-kit v1.0.1-0.20200525050818-198e65fa54c9/go.mod h1:8Pprmnq+2fFi5kJP0qcbwPl/fe22nro0OamjtwD0LJM=
github.com/meshplus/bitxhub-kit v1.0.1-0.20200525060338-39d86f7542ae h1:xp8+WxUWiGTiVYE0cAXm1m/A7sEGYLuV5WDMPFisRsQ=
github.com/meshplus/bitxhub-kit v1.0.1-0.20200525060338-39d86f7542ae/go.mod h1:8Pprmnq+2fFi5kJP0qcbwPl/fe22nro0OamjtwD0LJM=
github.com/meshplus/bitxhub-model v1.0.0-rc3 h1:oTyaDnhmMPKYifkV2Z5fH2OeY2RE7b6Bk6TzoOT9n4c=
github.com/meshplus/bitxhub-model v1.0.0-rc3/go.mod h1:ZCctQIYTlE3vJ8Lhkrgs9bWwNA+Dw4JzojOSIzLVU6E=
github.com/meshplus/bitxhub-model v1.0.0-rc4.0.20200427024612-57b479c1d610 h1:BOR7Kgllgx8rpJrqiG2NBU5cUn1ec9NoYozquXwLSLM=
github.com/meshplus/bitxhub-model v1.0.0-rc4.0.20200427024612-57b479c1d610/go.mod h1:ZCctQIYTlE3vJ8Lhkrgs9bWwNA+Dw4JzojOSIzLVU6E=
github.com/meshplus/bitxhub-model v1.0.0-rc4.0.20200429111056-62b55c3d4260/go.mod h1:QK8aACbxtZEA3Hk1BOCirW0uxMWLsMrLDpWz9FweIKM=
github.com/meshplus/bitxhub-model v1.0.0-rc4.0.20200514093243-7e8ae60d1c19 h1:D0n0/NqaueI6r+/cJIjYzWwjZ9j/5l36r/c8MYqTdXg=
github.com/meshplus/bitxhub-model v1.0.0-rc4.0.20200514093243-7e8ae60d1c19/go.mod h1:QK8aACbxtZEA3Hk1BOCirW0uxMWLsMrLDpWz9FweIKM=
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
github.com/miekg/dns v1.1.12/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
github.com/miekg/pkcs11 v1.0.3 h1:iMwmD7I5225wv84WxIG/bmxz9AXjWvTWIbM/TYHvWtw=
@ -632,8 +640,6 @@ github.com/prometheus/client_golang v1.4.1 h1:FFSuS004yOQEtDdTq+TAOLP5xUq63KqAFY
github.com/prometheus/client_golang v1.4.1/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU=
github.com/prometheus/client_golang v1.5.0 h1:Ctq0iGpCmr3jeP77kbF2UxgvRwzWWz+4Bh9/vJTyg1A=
github.com/prometheus/client_golang v1.5.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU=
github.com/prometheus/client_golang v1.6.0 h1:YVPodQOcK15POxhgARIvnDRVpLcuK8mglnMrWfyrw6A=
github.com/prometheus/client_golang v1.6.0/go.mod h1:ZLOG9ck3JLRdB5MgO8f+lLTe83AXG6ro35rLTxvnIl4=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910 h1:idejC8f05m9MGOsuEi1ATq9shN03HrxNkD/luQvxCv8=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90 h1:S/YWwWx/RA8rT8tKFRuGUZhuA90OyIBpPCXkcbwU8DE=
@ -656,8 +662,6 @@ github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsT
github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
github.com/prometheus/procfs v0.0.10 h1:QJQN3jYQhkamO4mhfUWqdDH2asK7ONOI9MTWjyAxNKM=
github.com/prometheus/procfs v0.0.10/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
github.com/prometheus/procfs v0.0.11 h1:DhHlBtkHWPYi8O2y31JkK0TF+DGM+51OopZjH/Ia5qI=
github.com/prometheus/procfs v0.0.11/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
github.com/prometheus/tsdb v0.6.2-0.20190402121629-4f204dcbc150/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
github.com/rcrowley/go-metrics v0.0.0-20190826022208-cac0b30c2563 h1:dY6ETXrvDG7Sa4vE8ZQG4yqWg6UnOcbqTAahkV813vQ=
@ -902,13 +906,10 @@ golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191210023423-ac6580df4449 h1:gSbV7h1NRL2G1xTg/owz62CST1oJBmxy4QpMMregXVQ=
golang.org/x/sys v0.0.0-20191210023423-ac6580df4449/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200219091948-cb0a6d8edb6c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527 h1:uYVVQ9WP/Ds2ROhcaGPeIdVq0RIXVLwsHlnvJ+cT1So=
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f h1:gWF768j/LaZugp8dyS4UwsslYCYz9XgFxvlgsn0n9H8=
golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=

View File

@ -34,6 +34,7 @@ type BlockExecutor struct {
persistC chan *ledger.BlockData
pendingBlockQ *cache.Cache
interchainCounter map[string][]uint64
normalTxs []types.Hash
validationEngine validator.Engine
currentHeight uint64
currentBlockHash types.Hash

View File

@ -63,7 +63,7 @@ func TestBlockExecutor_ExecuteBlock(t *testing.T) {
mockLedger.EXPECT().GetNonce(gomock.Any()).Return(uint64(0)).AnyTimes()
mockLedger.EXPECT().SetCode(gomock.Any(), gomock.Any()).AnyTimes()
mockLedger.EXPECT().GetCode(gomock.Any()).Return([]byte("10")).AnyTimes()
mockLedger.EXPECT().PersistExecutionResult(gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
mockLedger.EXPECT().PersistExecutionResult(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
mockLedger.EXPECT().FlushDirtyDataAndComputeJournal().Return(make(map[string]*ledger.Account), &ledger.BlockJournal{}).AnyTimes()
mockLedger.EXPECT().PersistBlockData(gomock.Any()).AnyTimes()
logger := log.NewWithModule("executor")
@ -181,7 +181,7 @@ func TestBlockExecutor_ExecuteBlock_Transfer(t *testing.T) {
account, journal := ledger.FlushDirtyDataAndComputeJournal()
err = ledger.Commit(1, account, journal)
require.Nil(t, err)
err = ledger.PersistExecutionResult(mockBlock(1, nil), nil)
err = ledger.PersistExecutionResult(mockBlock(1, nil), nil, nil)
require.Nil(t, err)
executor, err := New(ledger, log.NewWithModule("executor"))
@ -269,12 +269,21 @@ func mockTxData(t *testing.T, dataType pb.TransactionData_Type, vmType pb.Transa
}
func mockIBTP(t *testing.T, index uint64, typ pb.IBTP_Type) *pb.IBTP {
ibtppd, err := json.Marshal(pb.Payload{
content := pb.Content{
SrcContractId: from,
DstContractId: from,
Func: "set",
}
bytes, err := content.Marshal()
assert.Nil(t, err)
ibtppd, err := json.Marshal(pb.Payload{
Encrypted: false,
Content: bytes,
})
assert.Nil(t, err)
return &pb.IBTP{
From: from,
To: from,

View File

@ -1,14 +1,16 @@
package executor
import (
"bytes"
"encoding/json"
"fmt"
"sort"
"sync"
"sync/atomic"
"time"
"github.com/cbergoon/merkletree"
"github.com/meshplus/bitxhub-kit/crypto/asym"
"github.com/meshplus/bitxhub-kit/merkle/merkletree"
"github.com/meshplus/bitxhub-kit/types"
"github.com/meshplus/bitxhub-model/pb"
"github.com/meshplus/bitxhub/internal/ledger"
@ -57,12 +59,20 @@ func (exec *BlockExecutor) processExecuteEvent(block *pb.Block) {
receipts := exec.applyTransactions(validTxs)
receipts = append(receipts, invalidReceipts...)
root, receiptRoot, err := exec.calcMerkleRoots(block.Transactions, receipts)
calcMerkleStart := time.Now()
l1Root, l2Roots, err := exec.buildTxMerkleTree(block.Transactions)
if err != nil {
panic(err)
}
block.BlockHeader.TxRoot = root
receiptRoot, err := exec.calcReceiptMerkleRoot(receipts)
if err != nil {
panic(err)
}
calcMerkleDuration.Observe(float64(time.Since(calcMerkleStart)) / float64(time.Second))
block.BlockHeader.TxRoot = l1Root
block.BlockHeader.ReceiptRoot = receiptRoot
block.BlockHeader.ParentHash = exec.currentBlockHash
idx, err := json.Marshal(exec.interchainCounter)
@ -90,13 +100,80 @@ func (exec *BlockExecutor) processExecuteEvent(block *pb.Block) {
exec.currentBlockHash = block.BlockHash
exec.persistC <- &ledger.BlockData{
Block: block,
Receipts: receipts,
Accounts: accounts,
Journal: journal,
Block: block,
Receipts: receipts,
Accounts: accounts,
Journal: journal,
L2TxRoots: l2Roots,
}
}
func (exec *BlockExecutor) buildTxMerkleTree(txs []*pb.Transaction) (types.Hash, []types.Hash, error) {
var (
groupCnt = len(exec.interchainCounter) + 1
wg = sync.WaitGroup{}
lock = sync.Mutex{}
l2Roots = make([]types.Hash, 0, groupCnt)
errorCnt = int32(0)
)
wg.Add(groupCnt - 1)
for addr, txIndexes := range exec.interchainCounter {
go func(addr string, txIndexes []uint64) {
defer wg.Done()
txHashes := make([]merkletree.Content, 0, len(txIndexes))
for _, txIndex := range txIndexes {
txHashes = append(txHashes, pb.TransactionHash(txs[txIndex].TransactionHash.Bytes()))
}
hash, err := calcMerkleRoot(txHashes)
if err != nil {
atomic.AddInt32(&errorCnt, 1)
return
}
lock.Lock()
defer lock.Unlock()
l2Roots = append(l2Roots, hash)
}(addr, txIndexes)
}
txHashes := make([]merkletree.Content, 0, len(exec.normalTxs))
for _, txHash := range exec.normalTxs {
txHashes = append(txHashes, pb.TransactionHash(txHash.Bytes()))
}
hash, err := calcMerkleRoot(txHashes)
if err != nil {
atomic.AddInt32(&errorCnt, 1)
}
lock.Lock()
l2Roots = append(l2Roots, hash)
lock.Unlock()
wg.Wait()
if errorCnt != 0 {
return types.Hash{}, nil, fmt.Errorf("build tx merkle tree error")
}
sort.Slice(l2Roots, func(i, j int) bool {
return bytes.Compare(l2Roots[i].Bytes(), l2Roots[j].Bytes()) < 0
})
contents := make([]merkletree.Content, 0, groupCnt)
for _, l2Root := range l2Roots {
contents = append(contents, pb.TransactionHash(l2Root.Bytes()))
}
root, err := calcMerkleRoot(contents)
if err != nil {
return types.Hash{}, nil, err
}
return root, l2Roots, nil
}
func (exec *BlockExecutor) verifySign(block *pb.Block) ([]*pb.Transaction, []*pb.Receipt) {
if block.BlockHeader.Number == 1 {
return block.Transactions, nil
@ -161,6 +238,8 @@ func (exec *BlockExecutor) applyTransactions(txs []*pb.Transaction) []*pb.Receip
TxHash: tx.TransactionHash,
}
normalTx := true
ret, err := exec.applyTransaction(i, tx)
if err != nil {
receipt.Status = pb.Receipt_FAILED
@ -184,10 +263,15 @@ func (exec *BlockExecutor) applyTransactions(txs []*pb.Transaction) []*pb.Receip
for k, v := range m {
exec.interchainCounter[k] = append(exec.interchainCounter[k], v)
}
normalTx = false
}
}
}
if normalTx {
exec.normalTxs = append(exec.normalTxs, tx.TransactionHash)
}
receipts = append(receipts, receipt)
}
@ -247,42 +331,6 @@ func (exec *BlockExecutor) applyTransaction(i int, tx *pb.Transaction) ([]byte,
}
}
func (exec *BlockExecutor) calcMerkleRoot(txs []*pb.Transaction) (types.Hash, error) {
if len(txs) == 0 {
return types.Hash{}, nil
}
hashes := make([]interface{}, 0, len(txs))
for _, tx := range txs {
hashes = append(hashes, pb.TransactionHash(tx.TransactionHash.Bytes()))
}
tree := merkletree.NewMerkleTree()
err := tree.InitMerkleTree(hashes)
if err != nil {
return types.Hash{}, err
}
return types.Bytes2Hash(tree.GetMerkleRoot()), nil
}
func (exec *BlockExecutor) calcReceiptMerkleRoot(receipts []*pb.Receipt) (types.Hash, error) {
if len(receipts) == 0 {
return types.Hash{}, nil
}
hashes := make([]interface{}, 0, len(receipts))
for _, receipt := range receipts {
hashes = append(hashes, pb.TransactionHash(receipt.Hash().Bytes()))
}
tree := merkletree.NewMerkleTree()
err := tree.InitMerkleTree(hashes)
if err != nil {
return types.Hash{}, err
}
return types.Bytes2Hash(tree.GetMerkleRoot()), nil
}
func (exec *BlockExecutor) clear() {
exec.interchainCounter = make(map[string][]uint64)
exec.ledger.Clear()
@ -306,19 +354,32 @@ func (exec *BlockExecutor) transfer(from, to types.Address, value uint64) error
return nil
}
func (exec *BlockExecutor) calcMerkleRoots(txs []*pb.Transaction, receipts []*pb.Receipt) (types.Hash, types.Hash, error) {
func (exec *BlockExecutor) calcReceiptMerkleRoot(receipts []*pb.Receipt) (types.Hash, error) {
current := time.Now()
root, err := exec.calcMerkleRoot(txs)
receiptHashes := make([]merkletree.Content, 0, len(receipts))
for _, receipt := range receipts {
receiptHashes = append(receiptHashes, pb.TransactionHash(receipt.Hash().Bytes()))
}
receiptRoot, err := calcMerkleRoot(receiptHashes)
if err != nil {
return types.Hash{}, types.Hash{}, err
return types.Hash{}, err
}
receiptRoot, err := exec.calcReceiptMerkleRoot(receipts)
if err != nil {
return types.Hash{}, types.Hash{}, err
}
exec.logger.WithField("time", time.Since(current)).Debug("Calculate receipt merkle roots")
exec.logger.WithField("time", time.Since(current)).Debug("calculate merkle roots")
calcMerkleDuration.Observe(float64(time.Since(current)) / float64(time.Second))
return root, receiptRoot, nil
return receiptRoot, nil
}
func calcMerkleRoot(contents []merkletree.Content) (types.Hash, error) {
if len(contents) == 0 {
return types.Hash{}, nil
}
tree, err := merkletree.NewTree(contents)
if err != nil {
return types.Hash{}, err
}
return types.Bytes2Hash(tree.MerkleRoot()), nil
}

View File

@ -118,7 +118,7 @@ func (l *ChainLedger) GetReceipt(hash types.Hash) (*pb.Receipt, error) {
}
// PersistExecutionResult persist the execution result
func (l *ChainLedger) PersistExecutionResult(block *pb.Block, receipts []*pb.Receipt) error {
func (l *ChainLedger) PersistExecutionResult(block *pb.Block, receipts []*pb.Receipt, l2Roots []types.Hash) error {
current := time.Now()
if block == nil {
@ -139,6 +139,10 @@ func (l *ChainLedger) PersistExecutionResult(block *pb.Block, receipts []*pb.Rec
return err
}
if err := l.persistL2TxRoots(batcher, l2Roots, block.BlockHeader.Number); err != nil {
return err
}
// update chain meta in cache
count, err := getInterchainTxCount(block.BlockHeader)
if err != nil {
@ -258,6 +262,17 @@ func (l *ChainLedger) persistBlock(batcher storage.Batch, block *pb.Block) error
return nil
}
func (l *ChainLedger) persistL2TxRoots(batcher storage.Batch, l2Roots []types.Hash, height uint64) error {
roots, err := json.Marshal(l2Roots)
if err != nil {
return err
}
batcher.Put(compositeKey(l2TxRootsKey, height), roots)
return nil
}
func (l *ChainLedger) persistChainMeta(batcher storage.Batch, meta *pb.ChainMeta) error {
data, err := meta.Marshal()
if err != nil {

View File

@ -9,6 +9,7 @@ import (
const (
blockKey = "block-"
blockHashKey = "block-hash-"
l2TxRootsKey = "l2-tx-roots-"
receiptKey = "receipt-"
transactionKey = "tx-"
transactionMetaKey = "tx-meta-"

View File

@ -40,10 +40,11 @@ type ChainLedger struct {
}
type BlockData struct {
Block *pb.Block
Receipts []*pb.Receipt
Accounts map[string]*Account
Journal *BlockJournal
Block *pb.Block
Receipts []*pb.Receipt
Accounts map[string]*Account
Journal *BlockJournal
L2TxRoots []types.Hash
}
// New create a new ledger instance
@ -98,12 +99,13 @@ func (l *ChainLedger) PersistBlockData(blockData *BlockData) {
receipts := blockData.Receipts
accounts := blockData.Accounts
journal := blockData.Journal
l2Roots := blockData.L2TxRoots
if err := l.Commit(block.BlockHeader.Number, accounts, journal); err != nil {
panic(err)
}
if err := l.PersistExecutionResult(block, receipts); err != nil {
if err := l.PersistExecutionResult(block, receipts, l2Roots); err != nil {
panic(err)
}

View File

@ -101,7 +101,7 @@ type BlockchainLedger interface {
GetReceipt(hash types.Hash) (*pb.Receipt, error)
// PersistExecutionResult persist the execution result
PersistExecutionResult(block *pb.Block, receipts []*pb.Receipt) error
PersistExecutionResult(block *pb.Block, receipts []*pb.Receipt, l2Roots []types.Hash) error
// GetChainMeta get chain meta data
GetChainMeta() *pb.ChainMeta