diff options
-rw-r--r-- | consensus/dexcon/dexcon.go | 2 | ||||
-rw-r--r-- | core/blockchain.go | 26 | ||||
-rw-r--r-- | core/types/block.go | 49 | ||||
-rw-r--r-- | core/types/gen_header_json.go | 102 | ||||
-rw-r--r-- | dex/app.go | 20 |
5 files changed, 93 insertions, 106 deletions
diff --git a/consensus/dexcon/dexcon.go b/consensus/dexcon/dexcon.go index e636108f8..d8c181432 100644 --- a/consensus/dexcon/dexcon.go +++ b/consensus/dexcon/dexcon.go @@ -110,7 +110,7 @@ func (d *Dexcon) Prepare(chain consensus.ChainReader, header *types.Header) erro // Finalize implements consensus.Engine, ensuring no uncles are set, nor block // rewards given, and returns the final block. func (d *Dexcon) Finalize(chain consensus.ChainReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt) (*types.Block, error) { - config := d.configFetcher.DexconConfiguration(header.Position.Round) + config := d.configFetcher.DexconConfiguration(header.Round) reward := new(big.Int).Div(config.BlockReward, big.NewInt(int64(config.NumChains))) state.AddBalance(header.Coinbase, reward) header.Root = state.IntermediateRoot(true) diff --git a/core/blockchain.go b/core/blockchain.go index 43e528a2d..b38aa35dd 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -1507,13 +1507,13 @@ func (bc *BlockChain) insertSidechain(block *types.Block, it *insertIterator) (i return 0, nil, nil, nil } -func (bc *BlockChain) ProcessPendingBlock(block *types.Block) (int, error) { - n, events, logs, err := bc.processPendingBlock(block) +func (bc *BlockChain) ProcessPendingBlock(block *types.Block, witness *coreTypes.Witness) (int, error) { + n, events, logs, err := bc.processPendingBlock(block, witness) bc.PostChainEvents(events, logs) return n, err } -func (bc *BlockChain) processPendingBlock(block *types.Block) (int, []interface{}, []*types.Log, error) { +func (bc *BlockChain) processPendingBlock(block *types.Block, witness *coreTypes.Witness) (int, []interface{}, []*types.Log, error) { // Pre-checks passed, start the full block imports bc.wg.Add(1) defer bc.wg.Done() @@ -1531,6 +1531,12 @@ func (bc *BlockChain) processPendingBlock(block *types.Block) (int, []interface{ coalescedLogs []*types.Log ) + var witnessData types.WitnessData + if err := rlp.Decode(bytes.NewReader(witness.Data), &witnessData); err != nil { + log.Error("Witness rlp decode failed", "error", err) + panic(err) + } + // Start a parallel signature recovery (signer will fluke on fork transition, minimal perf loss) senderCacher.recoverFromBlocks(types.MakeSigner(bc.chainConfig, block.Number()), []*types.Block{block}) @@ -1541,13 +1547,15 @@ func (bc *BlockChain) processPendingBlock(block *types.Block) (int, []interface{ bstart := time.Now() currentBlock := bc.CurrentBlock() - if block.Header().WitnessHeight > currentBlock.NumberU64() && block.Header().WitnessHeight != 0 { - if bc.pendingBlocks[block.Header().WitnessHeight].block.Root() != block.Header().WitnessRoot { - return 0, nil, nil, fmt.Errorf("invalid witness root %s vs %s", bc.pendingBlocks[block.Header().WitnessHeight].block.Root().String(), block.Header().WitnessRoot.String()) + if witness.Height > currentBlock.NumberU64() && witness.Height != 0 { + if bc.pendingBlocks[witness.Height].block.Root() != witnessData.Root { + return 0, nil, nil, fmt.Errorf("invalid witness root %s vs %s", + bc.pendingBlocks[witness.Height].block.Root().String(), witnessData.Root.String()) } - if bc.pendingBlocks[block.Header().WitnessHeight].block.ReceiptHash() != block.Header().WitnessReceiptHash { - return 0, nil, nil, fmt.Errorf("invalid witness receipt hash %s vs %s", bc.pendingBlocks[block.Header().WitnessHeight].block.ReceiptHash().String(), block.Header().WitnessReceiptHash.String()) + if bc.pendingBlocks[witness.Height].block.ReceiptHash() != witnessData.ReceiptHash { + return 0, nil, nil, fmt.Errorf("invalid witness receipt hash %s vs %s", + bc.pendingBlocks[witness.Height].block.ReceiptHash().String(), witnessData.ReceiptHash.String()) } } @@ -1614,7 +1622,7 @@ func (bc *BlockChain) processPendingBlock(block *types.Block) (int, []interface{ }{block: newPendingBlock, receipts: receipts} // start insert available pending blocks into db - for pendingHeight := bc.CurrentBlock().NumberU64() + 1; pendingHeight <= block.Header().WitnessHeight; pendingHeight++ { + for pendingHeight := bc.CurrentBlock().NumberU64() + 1; pendingHeight <= witness.Height; pendingHeight++ { pendingIns, exist := bc.pendingBlocks[pendingHeight] if !exist { log.Error("Block has already inserted", "height", pendingHeight) diff --git a/core/types/block.go b/core/types/block.go index 73537b517..24750ba97 100644 --- a/core/types/block.go +++ b/core/types/block.go @@ -26,8 +26,7 @@ import ( "time" "unsafe" - coreTypes "github.com/dexon-foundation/dexon-consensus-core/core/types" - + coreTypes "github.com/dexon-foundation/dexon-consensus/core/types" "github.com/dexon-foundation/dexon/common" "github.com/dexon-foundation/dexon/common/hexutil" "github.com/dexon-foundation/dexon/rlp" @@ -66,31 +65,35 @@ func (n *BlockNonce) UnmarshalText(input []byte) error { return hexutil.UnmarshalFixedText("BlockNonce", input, n[:]) } +type WitnessData struct { + Root common.Hash + TxHash common.Hash + ReceiptHash common.Hash +} + //go:generate gencodec -type Header -field-override headerMarshaling -out gen_header_json.go // Header represents a block header in the Ethereum blockchain. type Header struct { - ParentHash common.Hash `json:"parentHash" gencodec:"required"` - UncleHash common.Hash `json:"sha3Uncles" gencodec:"required"` - Coinbase common.Address `json:"miner" gencodec:"required"` - Root common.Hash `json:"stateRoot" gencodec:"required"` - TxHash common.Hash `json:"transactionsRoot" gencodec:"required"` - ReceiptHash common.Hash `json:"receiptsRoot" gencodec:"required"` - Bloom Bloom `json:"logsBloom" gencodec:"required"` - Difficulty *big.Int `json:"difficulty" gencodec:"required"` - Number *big.Int `json:"number" gencodec:"required"` - GasLimit uint64 `json:"gasLimit" gencodec:"required"` - GasUsed uint64 `json:"gasUsed" gencodec:"required"` - Time uint64 `json:"timestamp" gencodec:"required"` - Extra []byte `json:"extraData" gencodec:"required"` - MixDigest common.Hash `json:"mixHash"` - Nonce BlockNonce `json:"nonce"` - Randomness []byte `json:"randomness" gencodec:"required"` - Position coreTypes.Position `json:"position" gencodec:"required"` - WitnessHeight uint64 `json:"witnessHeight" gencodec:"required"` - WitnessRoot common.Hash `json:"witnessRoot" gencodec:"required"` - WitnessReceiptHash common.Hash `json:"witnessReceiptHash" gencodec:"required"` - DexconMeta []byte `json:"dexconMeta" gencodec:"required"` + ParentHash common.Hash `json:"parentHash" gencodec:"required"` + UncleHash common.Hash `json:"sha3Uncles" gencodec:"required"` + Coinbase common.Address `json:"miner" gencodec:"required"` + Root common.Hash `json:"stateRoot" gencodec:"required"` + TxHash common.Hash `json:"transactionsRoot" gencodec:"required"` + ReceiptHash common.Hash `json:"receiptsRoot" gencodec:"required"` + Bloom Bloom `json:"logsBloom" gencodec:"required"` + Difficulty *big.Int `json:"difficulty" gencodec:"required"` + Number *big.Int `json:"number" gencodec:"required"` + GasLimit uint64 `json:"gasLimit" gencodec:"required"` + GasUsed uint64 `json:"gasUsed" gencodec:"required"` + Time uint64 `json:"timestamp" gencodec:"required"` + Extra []byte `json:"extraData" gencodec:"required"` + MixDigest common.Hash `json:"mixHash"` + Nonce BlockNonce `json:"nonce"` + Randomness []byte `json:"randomness" gencodec:"required"` + Position coreTypes.Position `json:"position" gencodec:"required"` + Round uint64 `json:"round" gencodec:"required"` + DexconMeta []byte `json:"dexconMeta" gencodec:"required"` } // field type overrides for gencodec diff --git a/core/types/gen_header_json.go b/core/types/gen_header_json.go index 72de5a457..dd2ca136e 100644 --- a/core/types/gen_header_json.go +++ b/core/types/gen_header_json.go @@ -7,9 +7,9 @@ import ( "errors" "math/big" + "github.com/dexon-foundation/dexon-consensus/core/types" "github.com/dexon-foundation/dexon/common" "github.com/dexon-foundation/dexon/common/hexutil" - "github.com/dexon-foundation/dexon/vendor/github.com/dexon-foundation/dexon-consensus-core/core/types" ) var _ = (*headerMarshaling)(nil) @@ -17,28 +17,26 @@ var _ = (*headerMarshaling)(nil) // MarshalJSON marshals as JSON. func (h Header) MarshalJSON() ([]byte, error) { type Header struct { - ParentHash common.Hash `json:"parentHash" gencodec:"required"` - UncleHash common.Hash `json:"sha3Uncles" gencodec:"required"` - Coinbase common.Address `json:"miner" gencodec:"required"` - Root common.Hash `json:"stateRoot" gencodec:"required"` - TxHash common.Hash `json:"transactionsRoot" gencodec:"required"` - ReceiptHash common.Hash `json:"receiptsRoot" gencodec:"required"` - Bloom Bloom `json:"logsBloom" gencodec:"required"` - Difficulty *hexutil.Big `json:"difficulty" gencodec:"required"` - Number *hexutil.Big `json:"number" gencodec:"required"` - GasLimit hexutil.Uint64 `json:"gasLimit" gencodec:"required"` - GasUsed hexutil.Uint64 `json:"gasUsed" gencodec:"required"` - Time hexutil.Uint64 `json:"timestamp" gencodec:"required"` - Extra hexutil.Bytes `json:"extraData" gencodec:"required"` - MixDigest common.Hash `json:"mixHash"` - Nonce BlockNonce `json:"nonce"` - Randomness hexutil.Bytes `json:"randomness" gencodec:"required"` - Position types.Position `json:"position" gencodec:"required"` - WitnessHeight uint64 `json:"witnessHeight" gencodec:"required"` - WitnessRoot common.Hash `json:"witnessRoot" gencodec:"required"` - WitnessReceiptHash common.Hash `json:"witnessReceiptHash" gencodec:"required"` - DexconMeta hexutil.Bytes `json:"dexconMeta" gencodec:"required"` - Hash common.Hash `json:"hash"` + ParentHash common.Hash `json:"parentHash" gencodec:"required"` + UncleHash common.Hash `json:"sha3Uncles" gencodec:"required"` + Coinbase common.Address `json:"miner" gencodec:"required"` + Root common.Hash `json:"stateRoot" gencodec:"required"` + TxHash common.Hash `json:"transactionsRoot" gencodec:"required"` + ReceiptHash common.Hash `json:"receiptsRoot" gencodec:"required"` + Bloom Bloom `json:"logsBloom" gencodec:"required"` + Difficulty *hexutil.Big `json:"difficulty" gencodec:"required"` + Number *hexutil.Big `json:"number" gencodec:"required"` + GasLimit hexutil.Uint64 `json:"gasLimit" gencodec:"required"` + GasUsed hexutil.Uint64 `json:"gasUsed" gencodec:"required"` + Time hexutil.Uint64 `json:"timestamp" gencodec:"required"` + Extra hexutil.Bytes `json:"extraData" gencodec:"required"` + MixDigest common.Hash `json:"mixHash"` + Nonce BlockNonce `json:"nonce"` + Randomness hexutil.Bytes `json:"randomness" gencodec:"required"` + Position types.Position `json:"position" gencodec:"required"` + Round uint64 `json:"round" gencodec:"required"` + DexconMeta hexutil.Bytes `json:"dexconMeta" gencodec:"required"` + Hash common.Hash `json:"hash"` } var enc Header enc.ParentHash = h.ParentHash @@ -58,9 +56,7 @@ func (h Header) MarshalJSON() ([]byte, error) { enc.Nonce = h.Nonce enc.Randomness = h.Randomness enc.Position = h.Position - enc.WitnessHeight = h.WitnessHeight - enc.WitnessRoot = h.WitnessRoot - enc.WitnessReceiptHash = h.WitnessReceiptHash + enc.Round = h.Round enc.DexconMeta = h.DexconMeta enc.Hash = h.Hash() return json.Marshal(&enc) @@ -69,27 +65,25 @@ func (h Header) MarshalJSON() ([]byte, error) { // UnmarshalJSON unmarshals from JSON. func (h *Header) UnmarshalJSON(input []byte) error { type Header struct { - ParentHash *common.Hash `json:"parentHash" gencodec:"required"` - UncleHash *common.Hash `json:"sha3Uncles" gencodec:"required"` - Coinbase *common.Address `json:"miner" gencodec:"required"` - Root *common.Hash `json:"stateRoot" gencodec:"required"` - TxHash *common.Hash `json:"transactionsRoot" gencodec:"required"` - ReceiptHash *common.Hash `json:"receiptsRoot" gencodec:"required"` - Bloom *Bloom `json:"logsBloom" gencodec:"required"` - Difficulty *hexutil.Big `json:"difficulty" gencodec:"required"` - Number *hexutil.Big `json:"number" gencodec:"required"` - GasLimit *hexutil.Uint64 `json:"gasLimit" gencodec:"required"` - GasUsed *hexutil.Uint64 `json:"gasUsed" gencodec:"required"` - Time *hexutil.Uint64 `json:"timestamp" gencodec:"required"` - Extra *hexutil.Bytes `json:"extraData" gencodec:"required"` - MixDigest *common.Hash `json:"mixHash"` - Nonce *BlockNonce `json:"nonce"` - Randomness *hexutil.Bytes `json:"randomness" gencodec:"required"` - Position *types.Position `json:"position" gencodec:"required"` - WitnessHeight *uint64 `json:"witnessHeight" gencodec:"required"` - WitnessRoot *common.Hash `json:"witnessRoot" gencodec:"required"` - WitnessReceiptHash *common.Hash `json:"witnessReceiptHash" gencodec:"required"` - DexconMeta *hexutil.Bytes `json:"dexconMeta" gencodec:"required"` + ParentHash *common.Hash `json:"parentHash" gencodec:"required"` + UncleHash *common.Hash `json:"sha3Uncles" gencodec:"required"` + Coinbase *common.Address `json:"miner" gencodec:"required"` + Root *common.Hash `json:"stateRoot" gencodec:"required"` + TxHash *common.Hash `json:"transactionsRoot" gencodec:"required"` + ReceiptHash *common.Hash `json:"receiptsRoot" gencodec:"required"` + Bloom *Bloom `json:"logsBloom" gencodec:"required"` + Difficulty *hexutil.Big `json:"difficulty" gencodec:"required"` + Number *hexutil.Big `json:"number" gencodec:"required"` + GasLimit *hexutil.Uint64 `json:"gasLimit" gencodec:"required"` + GasUsed *hexutil.Uint64 `json:"gasUsed" gencodec:"required"` + Time *hexutil.Uint64 `json:"timestamp" gencodec:"required"` + Extra *hexutil.Bytes `json:"extraData" gencodec:"required"` + MixDigest *common.Hash `json:"mixHash"` + Nonce *BlockNonce `json:"nonce"` + Randomness *hexutil.Bytes `json:"randomness" gencodec:"required"` + Position *types.Position `json:"position" gencodec:"required"` + Round *uint64 `json:"round" gencodec:"required"` + DexconMeta *hexutil.Bytes `json:"dexconMeta" gencodec:"required"` } var dec Header if err := json.Unmarshal(input, &dec); err != nil { @@ -161,18 +155,10 @@ func (h *Header) UnmarshalJSON(input []byte) error { return errors.New("missing required field 'position' for Header") } h.Position = *dec.Position - if dec.WitnessHeight == nil { - return errors.New("missing required field 'witnessHeight' for Header") + if dec.Round == nil { + return errors.New("missing required field 'round' for Header") } - h.WitnessHeight = *dec.WitnessHeight - if dec.WitnessRoot == nil { - return errors.New("missing required field 'witnessRoot' for Header") - } - h.WitnessRoot = *dec.WitnessRoot - if dec.WitnessReceiptHash == nil { - return errors.New("missing required field 'witnessReceiptHash' for Header") - } - h.WitnessReceiptHash = *dec.WitnessReceiptHash + h.Round = *dec.Round if dec.DexconMeta == nil { return errors.New("missing required field 'dexconMeta' for Header") } diff --git a/dex/app.go b/dex/app.go index b1558b46f..5193fdfb8 100644 --- a/dex/app.go +++ b/dex/app.go @@ -464,13 +464,6 @@ func (d *DexconApp) BlockDelivered(blockHash coreCommon.Hash, result coreTypes.F panic(err) } - var witnessData witnessData - err = rlp.Decode(bytes.NewReader(block.Witness.Data), &witnessData) - if err != nil { - log.Error("Witness rlp decode failed", "error", err) - panic(err) - } - block.Payload = nil dexconMeta, err := rlp.EncodeToBytes(block) if err != nil { @@ -478,21 +471,18 @@ func (d *DexconApp) BlockDelivered(blockHash coreCommon.Hash, result coreTypes.F } newBlock := types.NewBlock(&types.Header{ - Number: new(big.Int).SetUint64(result.Height), - Time: big.NewInt(result.Timestamp.Unix()), - Coinbase: common.BytesToAddress(block.ProposerID.Bytes()), - Position: block.Position, - WitnessHeight: block.Witness.Height, - WitnessRoot: witnessData.Root, - WitnessReceiptHash: witnessData.ReceiptHash, + Number: new(big.Int).SetUint64(result.Height), + Time: big.NewInt(result.Timestamp.Unix()), + Coinbase: common.BytesToAddress(block.ProposerID.Bytes()), // TODO(bojie): fix it GasLimit: 8000000, Difficulty: big.NewInt(1), + Round: block.Position.Round, DexconMeta: dexconMeta, Randomness: result.Randomness, }, transactions, nil, nil) - _, err = d.blockchain.ProcessPendingBlock(newBlock) + _, err = d.blockchain.ProcessPendingBlock(newBlock, &block.Witness) if err != nil { log.Error("Insert chain", "error", err) panic(err) |