From e6de60b80ee74540a9440e9f7c011f6df678cb41 Mon Sep 17 00:00:00 2001 From: atvanguard <93arpit@gmail.com> Date: Mon, 16 Mar 2020 20:17:48 +0530 Subject: [PATCH] TestCommitSpan finally works --- consensus/bor/bor.go | 44 ++++--------- consensus/bor_test/bor_test.go | 116 +++++++++++++-------------------- consensus/bor_test/span.json | 6 +- crypto/secp256k1/secp256.go | 1 + eth/api_backend.go | 2 - internal/ethapi/api.go | 2 +- les/api_backend.go | 3 + 7 files changed, 63 insertions(+), 111 deletions(-) diff --git a/consensus/bor/bor.go b/consensus/bor/bor.go index 3809edb17a..590d19c9d4 100644 --- a/consensus/bor/bor.go +++ b/consensus/bor/bor.go @@ -327,7 +327,6 @@ func (c *Bor) verifyHeader(chain consensus.ChainReader, header *types.Header, pa return errUnknownBlock } number := header.Number.Uint64() - // Don't waste time checking blocks from the future if header.Time > uint64(time.Now().Unix()) { return consensus.ErrFutureBlock @@ -339,10 +338,8 @@ func (c *Bor) verifyHeader(chain consensus.ChainReader, header *types.Header, pa if len(header.Extra) < extraVanity+extraSeal { return errMissingSignature } - // check extr adata isSprintEnd := (number+1)%c.config.Sprint == 0 - // Ensure that the extra-data contains a signer list on checkpoint, but none otherwise signersBytes := len(header.Extra) - extraVanity - extraSeal if !isSprintEnd && signersBytes != 0 { @@ -428,6 +425,7 @@ func (c *Bor) verifyCascadingFields(chain consensus.ChainReader, header *types.H } // All basic checks passed, verify the seal and return + // return nil return c.verifySeal(chain, header, parents) } @@ -564,7 +562,6 @@ func (c *Bor) verifySeal(chain consensus.ChainReader, header *types.Header, pare if err != nil { return err } - if !snap.ValidatorSet.HasAddress(signer.Bytes()) { return errUnauthorizedSigner } @@ -664,25 +661,22 @@ func (c *Bor) Prepare(chain consensus.ChainReader, header *types.Header) error { func (c *Bor) Finalize(chain consensus.ChainReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header) { // commit span headerNumber := header.Number.Uint64() - fmt.Println(header.Number, headerNumber % c.config.Sprint) + + // @todo check if this is required if /* headerNumber > 0 && */ - headerNumber % c.config.Sprint == 0 { + headerNumber%c.config.Sprint == 0 { cx := chainContext{Chain: chain, Bor: c} - fmt.Println("here 0.1") // check and commit span if err := c.checkAndCommitSpan(state, header, cx); err != nil { fmt.Println("Error while committing span", err) log.Error("Error while committing span", "error", err) return } - fmt.Println("here 11") // commit statees - // if err := c.CommitStates(state, header, cx); err != nil { - // log.Error("Error while committing states", "error", err) - // fmt.Println("here 12", err) - // return - // } - fmt.Println("here 12") + if err := c.CommitStates(state, header, cx); err != nil { + log.Error("Error while committing states", "error", err) + return + } } // No block rewards in PoA, so the state remains as is and uncles are dropped @@ -1017,21 +1011,15 @@ func (c *Bor) checkAndCommitSpan( var err error for i := 0; i < 2; i++ { - err = <- errors + err = <-errors if err != nil { - // fmt.Println(i, err) return err } } - fmt.Println("here 1") - // commit span if there is new span pending or span is ending or end block is not set if pending || c.needToCommitSpan(span, headerNumber) { - fmt.Println("here 2", span) - err := c.fetchAndCommitSpan(span.ID + 1, state, header, chain) - // err := c.commitSpan(span, state, header, chain) - fmt.Println("here 10", err) + err := c.fetchAndCommitSpan(span.ID+1, state, header, chain) return err } @@ -1039,8 +1027,6 @@ func (c *Bor) checkAndCommitSpan( } func (c *Bor) needToCommitSpan(span *Span, headerNumber uint64) bool { - fmt.Println("span", span) - // if span is nil if span == nil { return false @@ -1066,7 +1052,7 @@ func (c *Bor) fetchAndCommitSpan( chain core.ChainContext, ) error { response, err := c.HeimdallClient.FetchWithRetry("bor", "span", strconv.FormatUint(newSpanID, 10)) - fmt.Println("here 3") + if err != nil { return err } @@ -1075,7 +1061,6 @@ func (c *Bor) fetchAndCommitSpan( if err := json.Unmarshal(response.Result, &heimdallSpan); err != nil { return err } - // fmt.Println("here 4", heimdallSpan) // check if chain id matches with heimdall span if heimdallSpan.ChainID != c.chainConfig.ChainID.String() { return fmt.Errorf( @@ -1084,7 +1069,6 @@ func (c *Bor) fetchAndCommitSpan( c.chainConfig.ChainID, ) } - fmt.Println("here 5") // get validators bytes var validators []MinimalVal for _, val := range heimdallSpan.ValidatorSet.Validators { @@ -1094,7 +1078,6 @@ func (c *Bor) fetchAndCommitSpan( if err != nil { return err } - fmt.Println("here 6") // get producers bytes var producers []MinimalVal for _, val := range heimdallSpan.SelectedProducers { @@ -1114,7 +1097,6 @@ func (c *Bor) fetchAndCommitSpan( "validatorBytes", hex.EncodeToString(validatorBytes), "producerBytes", hex.EncodeToString(producerBytes), ) - fmt.Println("here 7") // get packed data data, err := c.validatorSetABI.Pack(method, big.NewInt(0).SetUint64(heimdallSpan.ID), @@ -1127,10 +1109,8 @@ func (c *Bor) fetchAndCommitSpan( log.Error("Unable to pack tx for commitSpan", "error", err) return err } - fmt.Println("here 8") // get system message msg := getSystemMessage(common.HexToAddress(c.config.ValidatorContract), data) - fmt.Println("here 9") // apply message return applyMessage(msg, state, header, c.chainConfig, chain) } @@ -1357,10 +1337,8 @@ func applyMessage( msg.Gas(), msg.Value(), ) - fmt.Println("here 9.1", err) // Update the state with pending changes if err != nil { - fmt.Println("here 9.2", err) state.Finalise(true) } return nil diff --git a/consensus/bor_test/bor_test.go b/consensus/bor_test/bor_test.go index 6517e7b126..afb88ca54c 100644 --- a/consensus/bor_test/bor_test.go +++ b/consensus/bor_test/bor_test.go @@ -3,23 +3,18 @@ package bor_test import ( "encoding/hex" "encoding/json" - "fmt" - - // "fmt" "io/ioutil" "math/big" "testing" "github.com/stretchr/testify/assert" - // "github.com/stretchr/testify/mock" - "github.com/maticnetwork/bor/common" "github.com/maticnetwork/bor/consensus/bor" "github.com/maticnetwork/bor/core" "github.com/maticnetwork/bor/core/rawdb" - // "github.com/maticnetwork/bor/core/state" + "github.com/maticnetwork/bor/crypto/secp256k1" + "github.com/maticnetwork/bor/core/types" - // "github.com/maticnetwork/bor/core/vm" "github.com/maticnetwork/bor/crypto" "github.com/maticnetwork/bor/eth" @@ -28,22 +23,22 @@ import ( "github.com/maticnetwork/bor/node" ) +const ( + extraSeal = 65 // Fixed number of extra-data suffix bytes reserved for signer seal +) + type initializeData struct { - genesis *core.Genesis + genesis *core.Genesis ethereum *eth.Ethereum } func TestCommitSpan(t *testing.T) { - var ( - // db = rawdb.NewMemoryDatabase() - // key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") - // addr = crypto.PubkeyToAddress(key.PublicKey) - ) init := buildEthereumInstance(t, rawdb.NewMemoryDatabase()) chain := init.ethereum.BlockChain() engine := init.ethereum.Engine() _bor := engine.(*bor.Bor) + // Mock HeimdallClient.FetchWithRetry to return span data from span.json spanData, err := ioutil.ReadFile("span.json") if err != nil { t.Fatalf("%s", err) @@ -52,78 +47,55 @@ func TestCommitSpan(t *testing.T) { if err := json.Unmarshal(spanData, res); err != nil { t.Fatalf("%s", err) } - h := &mocks.IHeimdallClient{} h.On("FetchWithRetry", "bor", "span", "1").Return(res, nil) _bor.SetHeimdallClient(h) + + // Build 1st blocks header db := init.ethereum.ChainDb() block := init.genesis.ToBlock(db) - statedb, err := chain.StateAt(block.Root()) - // statedb, _ := state.New(block.Root(), state.NewDatabase(db)) - // _, _, _, err = chain.Processor().Process(block, statedb, vm.Config{}) - // fmt.Println(err) - // _bor.Finalize(chain, block.Header(), statedb, nil, nil) - - api := bor.NewBorApi(chain, _bor) - validators, _ := api.GetCurrentValidators() - fmt.Println(1, validators) - - header := block.Header() + header := block.Header() // get 0th block header and mutate it as required header.Number = big.NewInt(1) header.ParentHash = block.Hash() - fmt.Println(block.Hash()) - // header.Hash = + header.Time += (init.genesis.Config.Bor.Period + 1) + header.Extra = make([]byte, 97) // vanity (32) + extraSeal (65) + privKey, _ := hex.DecodeString("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") + + statedb, err := chain.State() + if err != nil { + t.Fatalf("%s", err) + } + + block, err = _bor.FinalizeAndAssemble(chain, header, statedb, nil, nil, nil) + if err != nil { + t.Fatalf("%s", err) + } + + sig, err := secp256k1.Sign(crypto.Keccak256(bor.BorRLP(header)), privKey) + if err != nil { + t.Fatalf("%s", err) + } + copy(header.Extra[len(header.Extra)-extraSeal:], sig) + block = types.NewBlockWithHeader(header) + if _, err := chain.InsertChain([]*types.Block{block}); err != nil { + t.Fatalf("%s", err) + } - fmt.Println("statedb.IntermediateRoot", statedb.IntermediateRoot(true)) - _bor.Finalize(chain, block.Header(), statedb, nil, nil) - // _, _, _, err = chain.Processor().Process(block, statedb, vm.Config{}) - fmt.Println("statedb.IntermediateRoot 2", statedb.IntermediateRoot(true)) - statedb, err = chain.StateAt(block.Root()) - fmt.Println("statedb.IntermediateRoot 3", statedb.IntermediateRoot(true)) - + assert.True(t, h.AssertNumberOfCalls(t, "FetchWithRetry", 2)) + validators, err := _bor.GetCurrentValidators(1, 256) // new span starts at 256 if err != nil { t.Fatalf("%s", err) } - // fmt.Println(header.Number) - // _bor.Finalize(chain, header, statedb, nil, nil) - // status, err := chain.writeBlockWithState(block, receipts, statedb) - - // chain.chainmu.Lock() - td := big.NewInt(0) - td.Add(block.Difficulty(), chain.GetTdByHash(block.ParentHash())) - fmt.Println("td", td) - - rawdb.WriteTd(db, - block.Hash(), - block.NumberU64(), - td, - ) - rawdb.WriteBlock(db, block) - root, err := statedb.Commit(false) - fmt.Println("root", root) - if err != nil { + var heimdallSpan bor.HeimdallSpan + if err := json.Unmarshal(res.Result, &heimdallSpan); err != nil { t.Fatalf("%s", err) } - // if err := statedb.Reset(root); err != nil { - // t.Fatalf("state reset after block %d failed: %v", block.NumberU64(), err) - // } - // blockchain.chainmu.Unlock() - - assert.True(t, h.AssertNumberOfCalls(t, "FetchWithRetry", 1)) - validators, _ = api.GetCurrentValidators() - fmt.Println(2, validators) - - validators, _ = _bor.GetCurrentValidators(0, 255) - fmt.Println(3, validators) - - validators, _ = _bor.GetCurrentValidators(0, 256) - fmt.Println(4, validators) - - validators, _ = _bor.GetCurrentValidators(1, 256) - fmt.Println(4, validators) - // engine + for i, validator := range validators { + assert.Equal(t, validator.Address.Bytes(), heimdallSpan.SelectedProducers[i].Address.Bytes()) + assert.Equal(t, validator.VotingPower, heimdallSpan.SelectedProducers[i].VotingPower) + } } func TestIsValidatorAction(t *testing.T) { @@ -158,7 +130,7 @@ func TestIsValidatorAction(t *testing.T) { assert.True(t, engine.(*bor.Bor).IsValidatorAction(chain, addr, tx)) } -func buildEthereumInstance(t *testing.T, db ethdb.Database) (*initializeData) { +func buildEthereumInstance(t *testing.T, db ethdb.Database) *initializeData { genesisData, err := ioutil.ReadFile("genesis.json") if err != nil { t.Fatalf("%s", err) @@ -205,7 +177,7 @@ func buildEthereumInstance(t *testing.T, db ethdb.Database) (*initializeData) { stack.Service(ðereum) ethConf.Genesis.MustCommit(ethereum.ChainDb()) return &initializeData{ - genesis: gen, + genesis: gen, ethereum: ethereum, } } diff --git a/consensus/bor_test/span.json b/consensus/bor_test/span.json index 01e9427c47..f4be94eeb8 100644 --- a/consensus/bor_test/span.json +++ b/consensus/bor_test/span.json @@ -11,7 +11,7 @@ "endEpoch": 0, "power": 10000, "pubKey": "0x046434e10a34ade13c4fea917346a9fd1473eac2138a0b4e2a36426871918be63188fde4edbf598457592c9a49fe3b0036dd5497079495d132e5045bf499c4bdb1", - "signer": "0x1c4f0f054a0d6a1415382dc0fd83c6535188b220", + "signer": "0xc787af4624cb3e80ee23ae7faac0f2acea2be34c", "last_updated": 0, "accum": -40000 }, { @@ -47,7 +47,7 @@ "endEpoch": 0, "power": 10000, "pubKey": "0x0469536ae98030a7e83ec5ef3baffed2d05a32e31d978e58486f6bdb0fbbf240293838325116090190c0639db03f9cbd8b9aecfd269d016f46e3a2287fbf9ad232", - "signer": "0xc787af4624cb3e80ee23ae7faac0f2acea2be34c", + "signer": "0x1c4f0f054a0d6a1415382dc0fd83c6535188b220", "last_updated": 0, "accum": 10000 }], @@ -88,7 +88,7 @@ "pubKey": "0x0469536ae98030a7e83ec5ef3baffed2d05a32e31d978e58486f6bdb0fbbf240293838325116090190c0639db03f9cbd8b9aecfd269d016f46e3a2287fbf9ad232", "signer": "0xc787af4624cb3e80ee23ae7faac0f2acea2be34c", "last_updated": 0, - "accum": 10000 + "accum": 5000 }], "bor_chain_id": "15001" } diff --git a/crypto/secp256k1/secp256.go b/crypto/secp256k1/secp256.go index 35d0eef34a..191e158f05 100644 --- a/crypto/secp256k1/secp256.go +++ b/crypto/secp256k1/secp256.go @@ -59,6 +59,7 @@ func Sign(msg []byte, seckey []byte) ([]byte, error) { if len(msg) != 32 { return nil, ErrInvalidMsgLen } + if len(seckey) != 32 { return nil, ErrInvalidKey } diff --git a/eth/api_backend.go b/eth/api_backend.go index 6034f98f39..dbb57207d6 100644 --- a/eth/api_backend.go +++ b/eth/api_backend.go @@ -19,7 +19,6 @@ package eth import ( "context" "errors" - "fmt" "math/big" "github.com/maticnetwork/bor/accounts" @@ -102,7 +101,6 @@ func (b *EthAPIBackend) StateAndHeaderByNumber(ctx context.Context, blockNr rpc. return nil, nil, err } if header == nil { - fmt.Println("yoyo") return nil, nil, errors.New("header not found") } stateDb, err := b.eth.BlockChain().StateAt(header.Root) diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index 58eb78bb5a..7b56ba612e 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -730,7 +730,7 @@ func DoCall(ctx context.Context, b Backend, args CallArgs, blockNr rpc.BlockNumb defer func(start time.Time) { log.Debug("Executing EVM call finished", "runtime", time.Since(start)) }(time.Now()) state, header, err := b.StateAndHeaderByNumber(ctx, blockNr) - fmt.Println("statedb.IntermediateRoot in DoCall", state.IntermediateRoot(true)) + // fmt.Println("statedb.IntermediateRoot in DoCall", state.IntermediateRoot(false).Hex()) if state == nil || err != nil { return nil, 0, false, err } diff --git a/les/api_backend.go b/les/api_backend.go index 8333fdd8c3..4c6ee1f7a7 100644 --- a/les/api_backend.go +++ b/les/api_backend.go @@ -19,6 +19,7 @@ package les import ( "context" "errors" + "fmt" "math/big" "github.com/maticnetwork/bor/accounts" @@ -60,8 +61,10 @@ func (b *LesApiBackend) SetHead(number uint64) { func (b *LesApiBackend) HeaderByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*types.Header, error) { if blockNr == rpc.LatestBlockNumber || blockNr == rpc.PendingBlockNumber { + fmt.Println("20") return b.eth.blockchain.CurrentHeader(), nil } + fmt.Println("21") return b.eth.blockchain.GetHeaderByNumberOdr(ctx, uint64(blockNr)) }