Commit 91be16d4 authored by vicotor's avatar vicotor

update node and mockengine

parent 4d1c917e
......@@ -2,20 +2,26 @@ package engine
import (
"context"
"errors"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/exchain/go-exchain/exchain"
"github.com/exchain/go-exchain/exchain/chaindb"
nebulav1 "github.com/exchain/go-exchain/exchain/protocol/gen/go/nebula/v1"
"github.com/exchain/go-exchain/op-node/p2p"
"github.com/exchain/go-exchain/op-node/rollup"
"github.com/exchain/go-exchain/op-node/rollup/derive"
"github.com/exchain/go-exchain/op-node/rollup/driver"
"github.com/exchain/go-exchain/op-node/rollup/sync"
"github.com/exchain/go-exchain/op-service/eth"
"github.com/holiman/uint256"
"math/big"
)
type ExChainAPI struct {
chain chaindb.ChainDB
rollup *rollup.Config
chain chaindb.ChainDB
engine exchain.Engine
}
func (e *ExChainAPI) BlockRefByNumber(ctx context.Context, num uint64) (eth.BlockRef, error) {
......@@ -42,41 +48,74 @@ func (e *ExChainAPI) ChainID(ctx context.Context) (*big.Int, error) {
}
func (e *ExChainAPI) NewPayload(params exchain.PayloadParams) (exchain.ExecutionResult, error) {
//TODO implement me
panic("implement me")
result, err := e.engine.NewPayload(params)
if err != nil {
return exchain.ExecutionResult{}, err
}
if err = e.chain.SaveBlockData(result.Payload, &result.Receipts); err != nil {
return exchain.ExecutionResult{}, err
}
return result, nil
}
func (e *ExChainAPI) ProcessPayload(block *nebulav1.Block) error {
//TODO implement me
panic("implement me")
result, err := e.engine.ProcessPayload(block)
if err != nil {
return err
}
return e.chain.SaveBlockData(result.Payload, &result.Receipts)
}
func (e *ExChainAPI) PayloadByNumber(ctx context.Context, u uint64) (*eth.ExecutionPayloadEnvelope, error) {
//TODO implement me
panic("implement me")
block := e.chain.GetBlock(uint256.NewInt(u))
if block == nil {
return &eth.ExecutionPayloadEnvelope{}, errors.New("not found block")
}
payload := eth.NewExecutePayload(block)
return &eth.ExecutionPayloadEnvelope{
ExecutionPayload: payload,
ParentBeaconBlockRoot: nil, // todo: vicotor fill this field
}, nil
}
func (e *ExChainAPI) L2BlockRefByLabel(ctx context.Context, label eth.BlockLabel) (eth.L2BlockRef, error) {
//TODO implement me
panic("implement me")
switch label {
case eth.Safe, eth.Unsafe, eth.Finalized:
blk, err := e.chain.GetBlockByLabel(chaindb.ExChainBlockLatest)
if err != nil {
return eth.L2BlockRef{}, err
}
return derive.PayloadToBlockRef(e.rollup, eth.NewExecutePayload(blk))
default:
return eth.L2BlockRef{}, errors.New("unsupported label")
}
}
func (e *ExChainAPI) L2BlockRefByHash(ctx context.Context, l2Hash common.Hash) (eth.L2BlockRef, error) {
//TODO implement me
panic("implement me")
block := e.chain.BlockByHash(l2Hash)
if block == nil {
return eth.L2BlockRef{}, errors.New("not found block")
}
return derive.PayloadToBlockRef(e.rollup, eth.NewExecutePayload(block))
}
func (e *ExChainAPI) L2BlockRefByNumber(ctx context.Context, num uint64) (eth.L2BlockRef, error) {
//TODO implement me
panic("implement me")
block := e.chain.GetBlock(uint256.NewInt(num))
if block == nil {
return eth.L2BlockRef{}, errors.New("not found block")
}
return derive.PayloadToBlockRef(e.rollup, eth.NewExecutePayload(block))
}
func (e *ExChainAPI) SystemConfigByL2Hash(ctx context.Context, hash common.Hash) (eth.SystemConfig, error) {
//TODO implement me
panic("implement me")
block := e.chain.BlockByHash(hash)
if block == nil {
return eth.SystemConfig{}, errors.New("not found block")
}
return derive.PayloadToSystemConfig(e.rollup, eth.NewExecutePayload(block))
}
func (e *ExChainAPI) Close() {
func (e *ExChainAPI) Close() { // do nothing
}
var (
......@@ -85,8 +124,10 @@ var (
_ driver.L2Chain = (*ExChainAPI)(nil)
)
func NewEngineAPI(database chaindb.ChainDB) *ExChainAPI {
func NewEngineAPI(cfg *rollup.Config, database chaindb.ChainDB, engine exchain.Engine) *ExChainAPI {
return &ExChainAPI{
chain: database,
rollup: cfg,
chain: database,
engine: engine,
}
}
......@@ -23,6 +23,8 @@ import (
type ChainDB interface {
Database() metadb.Database
ChainId() (*uint256.Int, error)
GetBlockByLabel(label ExChainBlockLabel) (*nebulav1.Block, error)
SaveChainId(chainid *uint256.Int) error
CurrentHeight() uint256.Int
GetOriginBlockData(*uint256.Int) ([]byte, error)
GetBlock(*uint256.Int) *nebulav1.Block
......@@ -41,6 +43,15 @@ type ChainDB interface {
var (
big10 = uint256.NewInt(10)
big1 = uint256.NewInt(1)
big0 = uint256.NewInt(0)
)
type ExChainBlockLabel int
const (
ExChainBlockLatest ExChainBlockLabel = -1
ExChainBlockEarliest ExChainBlockLabel = 0
ExChainBlockFinalized ExChainBlockLabel = -2
)
func NewChainDB(database metadb.Database) ChainDB {
......@@ -81,6 +92,18 @@ type chaindb struct {
scope event.SubscriptionScope
}
func (m *chaindb) GetBlockByLabel(label ExChainBlockLabel) (*nebulav1.Block, error) {
switch label {
case ExChainBlockLatest, ExChainBlockFinalized:
latest := m.CurrentHeight()
return m.GetBlock(&latest), nil
case ExChainBlockEarliest:
return m.GetBlock(big0), nil
default:
return nil, errors.New("invalid block label")
}
}
func (m *chaindb) ChainId() (*uint256.Int, error) {
k := chainIdKey()
if v, err := m.database.Get([]byte(k)); err != nil {
......
......@@ -10,7 +10,7 @@ type Signer func(data []byte) ([]byte, error)
type Engine interface {
Start() error
NewPayload(params PayloadParams) (ExecutionResult, error)
ProcessPayload(block *nebulav1.Block) error
ProcessPayload(block *nebulav1.Block) (ExecutionResult, error)
}
type PayloadParams struct {
......@@ -24,22 +24,5 @@ type PayloadParams struct {
type ExecutionResult struct {
ParentRoot common.Hash
Payload *nebulav1.Block
}
type mockEngine struct{}
func (m mockEngine) Start() error {
return nil
}
func (m mockEngine) NewPayload(params PayloadParams) (ExecutionResult, error) {
return ExecutionResult{}, nil
}
func (m mockEngine) ProcessPayload(block *nebulav1.Block) error {
return nil
}
func NewEngine(database Database) Engine {
return &mockEngine{}
Receipts nebulav1.TransactionReceiptList
}
......@@ -56,6 +56,9 @@ func (ga *GenesisAlloc) UnmarshalJSON(data []byte) error {
func (g *GenesisBlock) Commit(db metadb.Database) (err error) {
chain := chaindb.NewChainDB(db)
blk := g.ToBlock()
if err := chain.SaveChainId(uint256.NewInt(g.ChainId)); err != nil {
return err
}
return chain.SaveBlockData(blk, nil)
}
......
package mockengine
import (
"fmt"
"github.com/ethereum/go-ethereum/common"
"github.com/exchain/go-exchain/exchain"
"github.com/exchain/go-exchain/exchain/chaindb"
nebulav1 "github.com/exchain/go-exchain/exchain/protocol/gen/go/nebula/v1"
"github.com/exchain/go-exchain/metadb"
log "github.com/sirupsen/logrus"
)
type MockEngine struct {
chain chaindb.ChainDB
}
func (m MockEngine) Start() error {
//TODO implement me
panic("implement me")
return nil
}
func (m MockEngine) NewPayload(params exchain.PayloadParams) (exchain.ExecutionResult, error) {
//TODO implement me
panic("implement me")
parent, err := m.chain.GetBlockByLabel(chaindb.ExChainBlockLatest)
if err != nil {
return exchain.ExecutionResult{}, err
}
root := params.ParentRoot
header := &nebulav1.BlockHeader{
Height: parent.Header.Height + 1,
ParentHash: parent.Header.Hash,
Timestamp: params.Timestamp,
L1Hash: params.ParentRoot.Bytes(),
Proposer: params.Proposer.Bytes(),
AppRoot: make([]byte, 0),
}
receipts, err := m.ProcessTx(header, params.Transactions)
if err != nil {
log.WithError(err).Error("failed to process txs")
return exchain.ExecutionResult{}, err
}
result := exchain.ExecutionResult{
ParentRoot: *root,
Payload: &nebulav1.Block{
Header: header,
Transactions: &params.Transactions,
},
Receipts: receipts,
}
return result, nil
}
func (m MockEngine) ProcessPayload(block *nebulav1.Block) error {
//TODO implement me
panic("implement me")
func (m MockEngine) ProcessPayload(block *nebulav1.Block) (exchain.ExecutionResult, error) {
parent, err := m.chain.GetBlockByLabel(chaindb.ExChainBlockLatest)
if err != nil {
return exchain.ExecutionResult{}, err
}
if parent.Header.Height+1 != block.Header.Height {
return exchain.ExecutionResult{}, fmt.Errorf("invalid block height")
}
receipts, err := m.ProcessTx(block.Header, *block.Transactions)
if err != nil {
return exchain.ExecutionResult{}, err
}
return exchain.ExecutionResult{
ParentRoot: common.BytesToHash(block.Header.L1Hash),
Payload: block,
Receipts: receipts,
}, nil
}
func NewEngine(database metadb.Database) exchain.Engine {
return &MockEngine{}
func NewEngine(chain chaindb.ChainDB) exchain.Engine {
return &MockEngine{
chain: chain,
}
}
package mockengine
import (
nebulav1 "github.com/exchain/go-exchain/exchain/protocol/gen/go/nebula/v1"
"github.com/exchain/go-exchain/exchain/wrapper"
)
func (m MockEngine) ProcessTx(header *nebulav1.BlockHeader, txs nebulav1.TransactionList) (nebulav1.TransactionReceiptList, error) {
receipts := nebulav1.TransactionReceiptList{
Receipts: make([]*nebulav1.TransactionReceipt, 0),
}
for _, tx := range txs.Txs {
wtx := wrapper.NewTxWrapper(tx)
receipt := &nebulav1.TransactionReceipt{
Hash: wtx.Hash().Bytes(),
TxType: tx.TxType,
Success: true,
BlockHeight: header.Height,
Timestamp: header.Timestamp,
}
switch tx.TxType {
case nebulav1.TxType_DepositTx:
receipt.Content = &nebulav1.TransactionReceipt_DepositR{
DepositR: &nebulav1.DepositReceipt{},
}
case nebulav1.TxType_LimitTx:
receipt.Content = &nebulav1.TransactionReceipt_LimitR{
LimitR: &nebulav1.LimitOrderReceipt{},
}
case nebulav1.TxType_WithdrawTx:
receipt.Content = &nebulav1.TransactionReceipt_WithdrawR{
WithdrawR: &nebulav1.WithdrawReceipt{},
}
case nebulav1.TxType_CancelTx:
receipt.Content = &nebulav1.TransactionReceipt_CancelR{
CancelR: &nebulav1.CancelOrderReceipt{},
}
case nebulav1.TxType_MarketTx:
receipt.Content = &nebulav1.TransactionReceipt_MarketR{
MarketR: &nebulav1.MarketOrderReceipt{},
}
case nebulav1.TxType_CreatePairTx:
receipt.Content = &nebulav1.TransactionReceipt_CreatePairR{
CreatePairR: &nebulav1.CreatePairReceipt{},
}
case nebulav1.TxType_DisablePairTx:
receipt.Content = &nebulav1.TransactionReceipt_DisablePairR{
DisablePairR: &nebulav1.DisablePairReceipt{},
}
case nebulav1.TxType_ProtocolTx:
receipt.Content = &nebulav1.TransactionReceipt_ProtocolR{
ProtocolR: &nebulav1.ProtocolTransactionReceipt{},
}
case nebulav1.TxType_SignProxyTx:
receipt.Content = &nebulav1.TransactionReceipt_SignProxyR{
SignProxyR: &nebulav1.SignProxyReceipt{},
}
default:
// TODO: return error
}
receipts.Receipts = append(receipts.Receipts, receipt)
}
return receipts, nil
}
package wrapper
import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
nebulav1 "github.com/exchain/go-exchain/exchain/protocol/gen/go/nebula/v1"
"github.com/golang/protobuf/proto"
)
type TxWrapper struct {
tx *nebulav1.Transaction
hash common.Hash
}
func NewTxWrapper(tx *nebulav1.Transaction) *TxWrapper {
return &TxWrapper{tx: tx}
}
func (t *TxWrapper) Hash() common.Hash {
if t.hash == (common.Hash{}) {
t.hash = t.calcHash()
}
return t.hash
}
func (t *TxWrapper) Clone() *nebulav1.Transaction {
return proto.Clone(t.tx).(*nebulav1.Transaction)
}
func (t *TxWrapper) calcHash() common.Hash {
ntx := t.Clone()
ntx.Signature = nil
data, _ := proto.Marshal(ntx)
return crypto.Keccak256Hash(data)
}
......@@ -397,10 +397,10 @@ func (n *OpNode) initL1BeaconAPI(ctx context.Context, cfg *Config) error {
func (n *OpNode) initL2(ctx context.Context, cfg *Config) error {
var err error
n.db = groupdb.NewGroupDB(n.cfg.NodeDataPath, "engine")
n.db = groupdb.NewGroupDB(n.cfg.NodeDataPath, "chain")
chain := chaindb.NewChainDB(n.db)
n.engineIns = mockengine.NewEngine(n.db)
n.l2Source = engine.NewEngineAPI(chain)
n.engineIns = mockengine.NewEngine(chain)
n.l2Source = engine.NewEngineAPI(&n.cfg.Rollup, chain, n.engineIns)
if n.engineIns == nil {
return errors.New("failed to create L2 engine")
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment