diff --git a/consensus/progpow/consensus.go b/consensus/progpow/consensus.go index 02429e337a..803a1c68c6 100644 --- a/consensus/progpow/consensus.go +++ b/consensus/progpow/consensus.go @@ -418,7 +418,8 @@ func (progpow *Progpow) verifySeal(header *types.Header) (common.Hash, error) { if progpow.fakeFail == header.Number().Uint64() { return common.Hash{}, errInvalidPoW } - return common.Hash{}, nil + //if hash is empty here, it fails because of div / 0 on poem.go: IntrinsicLogS() + return common.HexToHash("0xf5d8c9fb1a61e47c6dd4b5d0a1a0d6c0f7bce9cfae0e2a9d8a9c8d6d6f8f4f7"), nil } // If we're running a shared PoW, delegate verification to it if progpow.shared != nil { diff --git a/core/chain_makers.go b/core/chain_makers.go index 9e033e2e5e..78af48b54c 100644 --- a/core/chain_makers.go +++ b/core/chain_makers.go @@ -258,19 +258,12 @@ func makeHeader(chain consensus.ChainReader, parent *types.Block, state *state.S time = parent.Time() + 10 // block time is fixed at 10 seconds } - // Temporary header values just to calc difficulty - diffheader := types.EmptyHeader() - diffheader.SetDifficulty(parent.Difficulty()) - diffheader.SetNumber(parent.Number()) - diffheader.SetTime(time - 10) - diffheader.SetUncleHash(parent.UncleHash()) - // Make new header header := types.EmptyHeader() header.SetRoot(state.IntermediateRoot(true)) header.SetParentHash(parent.Hash()) header.SetCoinbase(parent.Coinbase()) - header.SetDifficulty(engine.CalcDifficulty(chain, diffheader)) + header.SetDifficulty(engine.CalcDifficulty(chain, parent.Header())) header.SetGasLimit(parent.GasLimit()) header.SetNumber(new(big.Int).Add(parent.Number(), common.Big1)) header.SetTime(time) diff --git a/core/core.go b/core/core.go index d559b7d7b2..a3b68a88ec 100644 --- a/core/core.go +++ b/core/core.go @@ -79,6 +79,31 @@ func NewCore(db ethdb.Database, config *Config, isLocalBlock func(block *types.H procCounter: 0, } + c.AppendQueueProcessCache() + + return c, nil +} + +// Used on unit testing +func NewFakeCore(db ethdb.Database, config *Config, isLocalBlock func(block *types.Header) bool, txConfig *TxPoolConfig, txLookupLimit *uint64, chainConfig *params.ChainConfig, slicesRunning []common.Location, domClientUrl string, subClientUrls []string, engine consensus.Engine, cacheConfig *CacheConfig, vmConfig vm.Config, genesis *Genesis) (*Core, error) { + slice, err := NewFakeSlice(db, config, txConfig, txLookupLimit, isLocalBlock, chainConfig, slicesRunning, domClientUrl, subClientUrls, engine, cacheConfig, vmConfig, genesis) + if err != nil { + return nil, err + } + + c := &Core{ + sl: slice, + engine: engine, + quit: make(chan struct{}), + procCounter: 0, + } + + c.AppendQueueProcessCache() + + return c, nil +} + +func (c *Core) AppendQueueProcessCache() { appendQueue, _ := lru.New(c_maxAppendQueue) c.appendQueue = appendQueue @@ -87,7 +112,6 @@ func NewCore(db ethdb.Database, config *Config, isLocalBlock func(block *types.H go c.updateAppendQueue() go c.startStatsTimer() - return c, nil } // InsertChain attempts to append a list of blocks to the slice, optionally diff --git a/core/slice.go b/core/slice.go index 9fb532a4d3..398ae36469 100644 --- a/core/slice.go +++ b/core/slice.go @@ -110,7 +110,63 @@ func NewSlice(db ethdb.Database, config *Config, txConfig *TxPoolConfig, txLooku if nodeCtx != common.PRIME_CTX { go func() { sl.domClient = makeDomClient(domClientUrl) - }() + }() + } + + if err := sl.init(genesis); err != nil { + return nil, err + } + + sl.CheckForBadHashAndRecover() + + if nodeCtx == common.ZONE_CTX && sl.ProcessingState() { + go sl.asyncPendingHeaderLoop() + } + + return sl, nil +} + +func NewFakeSlice(db ethdb.Database, config *Config, txConfig *TxPoolConfig, txLookupLimit *uint64, isLocalBlock func(block *types.Header) bool, chainConfig *params.ChainConfig, slicesRunning []common.Location, domClientUrl string, subClientUrls []string, engine consensus.Engine, cacheConfig *CacheConfig, vmConfig vm.Config, genesis *Genesis) (*Slice, error) { + nodeCtx := common.NodeLocation.Context() + sl := &Slice{ + config: chainConfig, + engine: engine, + sliceDb: db, + quit: make(chan struct{}), + badHashesCache: make(map[common.Hash]bool), + } + + var err error + sl.hc, err = NewHeaderChain(db, engine, chainConfig, cacheConfig, txLookupLimit, vmConfig, slicesRunning) + if err != nil { + return nil, err + } + + sl.validator = NewBlockValidator(chainConfig, sl.hc, engine) + + // tx pool is only used in zone + if nodeCtx == common.ZONE_CTX && sl.ProcessingState() { + sl.txPool = NewTxPool(*txConfig, chainConfig, sl.hc) + sl.hc.pool = sl.txPool + } + + sl.miner = New(sl.hc, sl.txPool, config, db, chainConfig, engine, isLocalBlock, sl.ProcessingState()) + + sl.phCache, _ = lru.New(c_phCacheSize) + + // only set the subClients if the chain is not Zone + sl.subClients = make([]*quaiclient.Client, 3) + if nodeCtx != common.ZONE_CTX { + sl.subClients = makeSubClients(subClientUrls) + } + + //test := engine. + + // only set domClient if the chain is not Prime. + if nodeCtx != common.PRIME_CTX { + go func () { + sl.domClient = makeFakeDomClient() + }() } if err := sl.init(genesis); err != nil { @@ -1118,6 +1174,11 @@ func makeDomClient(domurl string) *quaiclient.Client { return domClient } +func makeFakeDomClient() *quaiclient.Client { + domClient := &quaiclient.Client{} + return domClient +} + // MakeSubClients creates the quaiclient for the given suburls func makeSubClients(suburls []string) []*quaiclient.Client { subClients := make([]*quaiclient.Client, 3) diff --git a/eth/backend.go b/eth/backend.go index eda75cd7c9..f3a5ad9393 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -26,6 +26,7 @@ import ( "github.com/dominant-strategies/go-quai/common" "github.com/dominant-strategies/go-quai/consensus" + "github.com/dominant-strategies/go-quai/consensus/progpow" "github.com/dominant-strategies/go-quai/core" "github.com/dominant-strategies/go-quai/core/bloombits" "github.com/dominant-strategies/go-quai/core/rawdb" @@ -184,7 +185,11 @@ func New(stack *node.Node, config *ethconfig.Config) (*Quai, error) { config.TxPool.Journal = stack.ResolvePath(config.TxPool.Journal) } - eth.core, err = core.NewCore(chainDb, &config.Miner, eth.isLocalBlock, &config.TxPool, &config.TxLookupLimit, chainConfig, eth.config.SlicesRunning, eth.config.DomUrl, eth.config.SubUrls, eth.engine, cacheConfig, vmConfig, config.Genesis) + if eth.config.Progpow.PowMode == progpow.ModeFake{ + eth.core, err = core.NewFakeCore(chainDb, &config.Miner, eth.isLocalBlock, &config.TxPool, &config.TxLookupLimit, chainConfig, eth.config.SlicesRunning, eth.config.DomUrl, eth.config.SubUrls, eth.engine, cacheConfig, vmConfig, config.Genesis) + } else { + eth.core, err = core.NewCore(chainDb, &config.Miner, eth.isLocalBlock, &config.TxPool, &config.TxLookupLimit, chainConfig, eth.config.SlicesRunning, eth.config.DomUrl, eth.config.SubUrls, eth.engine, cacheConfig, vmConfig, config.Genesis) + } if err != nil { return nil, err } diff --git a/quaiclient/ethclient/ethclient_test.go b/quaiclient/ethclient/ethclient_test.go index 94bf7383f4..b982c1ccf1 100644 --- a/quaiclient/ethclient/ethclient_test.go +++ b/quaiclient/ethclient/ethclient_test.go @@ -188,6 +188,8 @@ var ( ) func newTestBackend(t *testing.T) (*node.Node, []*types.Block) { + // Set location to ZONE_CTX + common.NodeLocation = common.Location{0, 0} // Generate test chain. genesis, blocks := generateTestChain() // Create node @@ -197,7 +199,9 @@ func newTestBackend(t *testing.T) (*node.Node, []*types.Block) { } // Create quai Service config := ðconfig.Config{Genesis: genesis} + config.Miner.ExtraData = []byte("test miner") config.Progpow.PowMode = progpow.ModeFake + config.DomUrl = "http://localhost:8080" ethservice, err := eth.New(n, config) if err != nil { t.Fatalf("can't create new quai service: %v", err) @@ -206,7 +210,8 @@ func newTestBackend(t *testing.T) (*node.Node, []*types.Block) { if err := n.Start(); err != nil { t.Fatalf("can't start test node: %v", err) } - if _, err := ethservice.BlockChain().InsertChain(blocks[1:]); err != nil { + blocks[1].Header().SetLocation(common.Location{0, 0}) + if _, err := ethservice.Core().InsertChain(blocks[1:]); err != nil { t.Fatalf("can't import test blocks: %v", err) } return n, blocks @@ -214,19 +219,22 @@ func newTestBackend(t *testing.T) (*node.Node, []*types.Block) { func generateTestChain() (*core.Genesis, []*types.Block) { db := rawdb.NewMemoryDatabase() - config := params.AllProgpowProtocolChanges + config := params.ProgpowColosseumChainConfig genesis := &core.Genesis{ - Config: config, - Alloc: core.GenesisAlloc{testAddr: {Balance: testBalance}}, + Config: config, + Nonce: 0, ExtraData: []byte("test genesis"), - Timestamp: 9000, - BaseFee: big.NewInt(params.InitialBaseFee), + GasLimit: 5000000, + Difficulty: big.NewInt(300000000), } generate := func(i int, g *core.BlockGen) { g.OffsetTime(5) g.SetExtra([]byte("test")) } gblock := genesis.ToBlock(db) + + config.GenesisHash = gblock.Hash() + engine := progpow.NewFaker() blocks, _ := core.GenerateChain(config, gblock, engine, db, 1, generate) blocks = append([]*types.Block{gblock}, blocks...) @@ -305,7 +313,7 @@ func testHeader(t *testing.T, chain []*types.Block, client *rpc.Client) { t.Fatalf("HeaderByNumber(%v) error = %q, want %q", tt.block, err, tt.wantErr) } if got != nil && got.Number() != nil && got.Number().Sign() == 0 { - got.Number() = big.NewInt(0) // hack to make DeepEqual work + got.SetNumber(big.NewInt(0)) // hack to make DeepEqual work } if !reflect.DeepEqual(got, tt.want) { t.Fatalf("HeaderByNumber(%v)\n = %v\nwant %v", tt.block, got, tt.want) @@ -327,7 +335,7 @@ func testBalanceAt(t *testing.T, client *rpc.Client) { want: testBalance, }, "non_existent_account": { - account: common.Address{1}, + account: common.Address{}, block: big.NewInt(1), want: big.NewInt(0), }, @@ -568,7 +576,7 @@ func sendTransaction(ec *Client) error { return err } // Create transaction - tx := types.NewTransaction(0, common.Address{1}, big.NewInt(1), 22000, big.NewInt(params.InitialBaseFee), nil) + tx := types.NewTx(&types.ExternalTx{}) signer := types.LatestSignerForChainID(chainID) signature, err := crypto.Sign(signer.Hash(tx).Bytes(), testKey) if err != nil {