فهرست منبع

Merge pull request #506 from binance-chain/develop

[R4R] Release v1.1.4
yutianwu 4 سال پیش
والد
کامیت
30972a7b7b

+ 1 - 4
.github/workflows/unit-test.yml

@@ -43,13 +43,10 @@ jobs:
         restore-keys: |
         restore-keys: |
           ${{ runner.os }}-go-
           ${{ runner.os }}-go-
 
 
-    - name: Test Build
-      run: |
-        make geth
-
     - name: Uint Test
     - name: Uint Test
       env:
       env:
         ANDROID_HOME: "" # Skip android test
         ANDROID_HOME: "" # Skip android test
       run: |
       run: |
+        go clean -testcache
         make test
         make test
 
 

+ 12 - 0
CHANGELOG.md

@@ -1,4 +1,16 @@
 # Changelog
 # Changelog
+## v1.1.4
+Improvement
+* [\#472](https://github.com/binance-chain/bsc/pull/472) add metrics for contract code bitmap cache
+* [\#473](https://github.com/binance-chain/bsc/pull/473) fix ci test flow
+
+BUGFIX
+* [\#491](https://github.com/binance-chain/bsc/pull/491) fix prefetcher related bugs
+
+FEATURES
+* [\#480](https://github.com/binance-chain/bsc/pull/480) implement bep 95
+
+
 ## v1.1.3
 ## v1.1.3
 Improvement
 Improvement
 * [\#456](https://github.com/binance-chain/bsc/pull/456) git-flow support lint, unit test, and integration test
 * [\#456](https://github.com/binance-chain/bsc/pull/456) git-flow support lint, unit test, and integration test

+ 5 - 3
core/block_validator.go

@@ -144,13 +144,15 @@ func (v *BlockValidator) ValidateState(block *types.Block, statedb *state.StateD
 			validateRes <- tmpFunc()
 			validateRes <- tmpFunc()
 		}()
 		}()
 	}
 	}
+
+	var err error
 	for i := 0; i < len(validateFuns); i++ {
 	for i := 0; i < len(validateFuns); i++ {
 		r := <-validateRes
 		r := <-validateRes
-		if r != nil {
-			return r
+		if r != nil && err == nil {
+			err = r
 		}
 		}
 	}
 	}
-	return nil
+	return err
 }
 }
 
 
 // CalcGasLimit computes the gas limit of the next block after parent. It aims
 // CalcGasLimit computes the gas limit of the next block after parent. It aims

+ 18 - 16
core/blockchain.go

@@ -2486,9 +2486,12 @@ func (bc *BlockChain) update() {
 }
 }
 
 
 func (bc *BlockChain) trustedDiffLayerLoop() {
 func (bc *BlockChain) trustedDiffLayerLoop() {
-	recheck := time.Tick(diffLayerFreezerRecheckInterval)
+	recheck := time.NewTicker(diffLayerFreezerRecheckInterval)
 	bc.wg.Add(1)
 	bc.wg.Add(1)
-	defer bc.wg.Done()
+	defer func() {
+		bc.wg.Done()
+		recheck.Stop()
+	}()
 	for {
 	for {
 		select {
 		select {
 		case diff := <-bc.diffQueueBuffer:
 		case diff := <-bc.diffQueueBuffer:
@@ -2521,29 +2524,28 @@ func (bc *BlockChain) trustedDiffLayerLoop() {
 				batch.Reset()
 				batch.Reset()
 			}
 			}
 			return
 			return
-		case <-recheck:
+		case <-recheck.C:
 			currentHeight := bc.CurrentBlock().NumberU64()
 			currentHeight := bc.CurrentBlock().NumberU64()
 			var batch ethdb.Batch
 			var batch ethdb.Batch
 			for !bc.diffQueue.Empty() {
 			for !bc.diffQueue.Empty() {
 				diff, prio := bc.diffQueue.Pop()
 				diff, prio := bc.diffQueue.Pop()
 				diffLayer := diff.(*types.DiffLayer)
 				diffLayer := diff.(*types.DiffLayer)
 
 
-				// if the block old enough
-				if int64(currentHeight)+prio >= int64(bc.triesInMemory) {
-					canonicalHash := bc.GetCanonicalHash(uint64(-prio))
-					// on the canonical chain
-					if canonicalHash == diffLayer.BlockHash {
-						if batch == nil {
-							batch = bc.db.DiffStore().NewBatch()
-						}
-						rawdb.WriteDiffLayer(batch, diffLayer.BlockHash, diffLayer)
-						staleHash := bc.GetCanonicalHash(uint64(-prio) - bc.diffLayerFreezerBlockLimit)
-						rawdb.DeleteDiffLayer(batch, staleHash)
-					}
-				} else {
+				// if the block not old enough
+				if int64(currentHeight)+prio < int64(bc.triesInMemory) {
 					bc.diffQueue.Push(diffLayer, prio)
 					bc.diffQueue.Push(diffLayer, prio)
 					break
 					break
 				}
 				}
+				canonicalHash := bc.GetCanonicalHash(uint64(-prio))
+				// on the canonical chain
+				if canonicalHash == diffLayer.BlockHash {
+					if batch == nil {
+						batch = bc.db.DiffStore().NewBatch()
+					}
+					rawdb.WriteDiffLayer(batch, diffLayer.BlockHash, diffLayer)
+					staleHash := bc.GetCanonicalHash(uint64(-prio) - bc.diffLayerFreezerBlockLimit)
+					rawdb.DeleteDiffLayer(batch, staleHash)
+				}
 				if batch != nil && batch.ValueSize() > ethdb.IdealBatchSize {
 				if batch != nil && batch.ValueSize() > ethdb.IdealBatchSize {
 					if err := batch.Write(); err != nil {
 					if err := batch.Write(); err != nil {
 						panic(fmt.Sprintf("Failed to write diff layer, error %v", err))
 						panic(fmt.Sprintf("Failed to write diff layer, error %v", err))

+ 5 - 1
core/blockchain_diff_test.go

@@ -280,10 +280,14 @@ func TestFreezeDiffLayer(t *testing.T) {
 	blockNum := 1024
 	blockNum := 1024
 	fullBackend := newTestBackend(blockNum, true)
 	fullBackend := newTestBackend(blockNum, true)
 	defer fullBackend.close()
 	defer fullBackend.close()
+	for len(fullBackend.chain.diffQueueBuffer) > 0 {
+		// Wait for the buffer to be zero.
+	}
 	// Minus one empty block.
 	// Minus one empty block.
 	if fullBackend.chain.diffQueue.Size() != blockNum-1 {
 	if fullBackend.chain.diffQueue.Size() != blockNum-1 {
-		t.Errorf("size of diff queue is wrong, expected: %d, get: %d", blockNum, fullBackend.chain.diffQueue.Size())
+		t.Errorf("size of diff queue is wrong, expected: %d, get: %d", blockNum-1, fullBackend.chain.diffQueue.Size())
 	}
 	}
+
 	time.Sleep(diffLayerFreezerRecheckInterval + 1*time.Second)
 	time.Sleep(diffLayerFreezerRecheckInterval + 1*time.Second)
 	if fullBackend.chain.diffQueue.Size() != int(fullBackend.chain.triesInMemory) {
 	if fullBackend.chain.diffQueue.Size() != int(fullBackend.chain.triesInMemory) {
 		t.Errorf("size of diff queue is wrong, expected: %d, get: %d", blockNum, fullBackend.chain.diffQueue.Size())
 		t.Errorf("size of diff queue is wrong, expected: %d, get: %d", blockNum, fullBackend.chain.diffQueue.Size())

+ 2 - 2
core/blockchain_test.go

@@ -1568,8 +1568,8 @@ func TestLargeReorgTrieGC(t *testing.T) {
 		t.Fatalf("failed to finalize competitor chain: %v", err)
 		t.Fatalf("failed to finalize competitor chain: %v", err)
 	}
 	}
 	for i, block := range competitor[:len(competitor)-TestTriesInMemory] {
 	for i, block := range competitor[:len(competitor)-TestTriesInMemory] {
-		if node, _ := chain.stateCache.TrieDB().Node(block.Root()); node != nil {
-			t.Fatalf("competitor %d: competing chain state missing", i)
+		if node, err := chain.stateCache.TrieDB().Node(block.Root()); node != nil {
+			t.Fatalf("competitor %d: competing chain state missing, err: %v", i, err)
 		}
 		}
 	}
 	}
 }
 }

+ 13 - 1
core/state/snapshot/generate.go

@@ -560,6 +560,12 @@ func (dl *diskLayer) generate(stats *generatorStats) {
 		default:
 		default:
 		}
 		}
 		if batch.ValueSize() > ethdb.IdealBatchSize || abort != nil {
 		if batch.ValueSize() > ethdb.IdealBatchSize || abort != nil {
+			if bytes.Compare(currentLocation, dl.genMarker) < 0 {
+				log.Error("Snapshot generator went backwards",
+					"currentLocation", fmt.Sprintf("%x", currentLocation),
+					"genMarker", fmt.Sprintf("%x", dl.genMarker))
+			}
+
 			// Flush out the batch anyway no matter it's empty or not.
 			// Flush out the batch anyway no matter it's empty or not.
 			// It's possible that all the states are recovered and the
 			// It's possible that all the states are recovered and the
 			// generation indeed makes progress.
 			// generation indeed makes progress.
@@ -634,8 +640,14 @@ func (dl *diskLayer) generate(stats *generatorStats) {
 			stats.storage += common.StorageSize(1 + common.HashLength + dataLen)
 			stats.storage += common.StorageSize(1 + common.HashLength + dataLen)
 			stats.accounts++
 			stats.accounts++
 		}
 		}
+		marker := accountHash[:]
+		// If the snap generation goes here after interrupted, genMarker may go backward
+		// when last genMarker is consisted of accountHash and storageHash
+		if accMarker != nil && bytes.Equal(marker, accMarker) && len(dl.genMarker) > common.HashLength {
+			marker = dl.genMarker[:]
+		}
 		// If we've exceeded our batch allowance or termination was requested, flush to disk
 		// If we've exceeded our batch allowance or termination was requested, flush to disk
-		if err := checkAndFlush(accountHash[:]); err != nil {
+		if err := checkAndFlush(marker); err != nil {
 			return err
 			return err
 		}
 		}
 		// If the iterated account is the contract, create a further loop to
 		// If the iterated account is the contract, create a further loop to

+ 1 - 0
core/state/statedb.go

@@ -958,6 +958,7 @@ func (s *StateDB) Finalise(deleteEmptyObjects bool) {
 // goes into transaction receipts.
 // goes into transaction receipts.
 func (s *StateDB) IntermediateRoot(deleteEmptyObjects bool) common.Hash {
 func (s *StateDB) IntermediateRoot(deleteEmptyObjects bool) common.Hash {
 	if s.lightProcessed {
 	if s.lightProcessed {
+		s.StopPrefetcher()
 		return s.trie.Hash()
 		return s.trie.Hash()
 	}
 	}
 	// Finalise all the dirty storage states and write them into the tries
 	// Finalise all the dirty storage states and write them into the tries

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 9 - 0
core/systemcontracts/upgrade.go


+ 9 - 1
core/vm/contract.go

@@ -22,12 +22,18 @@ import (
 	lru "github.com/hashicorp/golang-lru"
 	lru "github.com/hashicorp/golang-lru"
 
 
 	"github.com/ethereum/go-ethereum/common"
 	"github.com/ethereum/go-ethereum/common"
+	"github.com/ethereum/go-ethereum/metrics"
 	"github.com/holiman/uint256"
 	"github.com/holiman/uint256"
 )
 )
 
 
 const codeBitmapCacheSize = 2000
 const codeBitmapCacheSize = 2000
 
 
-var codeBitmapCache, _ = lru.New(codeBitmapCacheSize)
+var (
+	codeBitmapCache, _ = lru.New(codeBitmapCacheSize)
+
+	contractCodeBitmapHitMeter  = metrics.NewRegisteredMeter("vm/contract/code/bitmap/hit", nil)
+	contractCodeBitmapMissMeter = metrics.NewRegisteredMeter("vm/contract/code/bitmap/miss", nil)
+)
 
 
 // ContractRef is a reference to the contract's backing object
 // ContractRef is a reference to the contract's backing object
 type ContractRef interface {
 type ContractRef interface {
@@ -117,12 +123,14 @@ func (c *Contract) isCode(udest uint64) bool {
 		analysis, exist := c.jumpdests[c.CodeHash]
 		analysis, exist := c.jumpdests[c.CodeHash]
 		if !exist {
 		if !exist {
 			if cached, ok := codeBitmapCache.Get(c.CodeHash); ok {
 			if cached, ok := codeBitmapCache.Get(c.CodeHash); ok {
+				contractCodeBitmapHitMeter.Mark(1)
 				analysis = cached.(bitvec)
 				analysis = cached.(bitvec)
 			} else {
 			} else {
 				// Do the analysis and save in parent context
 				// Do the analysis and save in parent context
 				// We do not need to store it in c.analysis
 				// We do not need to store it in c.analysis
 				analysis = codeBitmap(c.Code)
 				analysis = codeBitmap(c.Code)
 				c.jumpdests[c.CodeHash] = analysis
 				c.jumpdests[c.CodeHash] = analysis
+				contractCodeBitmapMissMeter.Mark(1)
 				codeBitmapCache.Add(c.CodeHash, analysis)
 				codeBitmapCache.Add(c.CodeHash, analysis)
 			}
 			}
 		}
 		}

+ 1 - 4
docker/Dockerfile.truffle

@@ -7,10 +7,7 @@ RUN git clone https://github.com/binance-chain/canonical-upgradeable-bep20.git /
 WORKDIR /usr/app/canonical-upgradeable-bep20
 WORKDIR /usr/app/canonical-upgradeable-bep20
 COPY docker/truffle-config.js /usr/app/canonical-upgradeable-bep20
 COPY docker/truffle-config.js /usr/app/canonical-upgradeable-bep20
 
 
-RUN npm install -g n
-RUN n 12.18.3 && node -v
-
-RUN npm install -g truffle@v5.1.14
+RUN npm install -g --unsafe-perm truffle@v5.1.14
 RUN npm install
 RUN npm install
 
 
 ENTRYPOINT [ "/bin/bash" ]
 ENTRYPOINT [ "/bin/bash" ]

+ 1 - 0
eth/catalyst/api_test.go

@@ -82,6 +82,7 @@ func generateTestChainWithFork(n int, fork int) (*core.Genesis, []*types.Block,
 		RamanujanBlock:      big.NewInt(0),
 		RamanujanBlock:      big.NewInt(0),
 		NielsBlock:          big.NewInt(0),
 		NielsBlock:          big.NewInt(0),
 		MirrorSyncBlock:     big.NewInt(0),
 		MirrorSyncBlock:     big.NewInt(0),
+		BrunoBlock:          big.NewInt(0),
 
 
 		Ethash: new(params.EthashConfig),
 		Ethash: new(params.EthashConfig),
 	}
 	}

+ 29 - 5
params/config.go

@@ -34,7 +34,7 @@ var (
 
 
 	BSCGenesisHash    = common.HexToHash("0x0d21840abff46b96c84b2ac9e10e4f5cdaeb5693cb665db62a2f3b02d2d57b5b")
 	BSCGenesisHash    = common.HexToHash("0x0d21840abff46b96c84b2ac9e10e4f5cdaeb5693cb665db62a2f3b02d2d57b5b")
 	ChapelGenesisHash = common.HexToHash("0x6d3c66c5357ec91d5c43af47e234a939b22557cbb552dc45bebbceeed90fbe34")
 	ChapelGenesisHash = common.HexToHash("0x6d3c66c5357ec91d5c43af47e234a939b22557cbb552dc45bebbceeed90fbe34")
-	RialtoGenesisHash = common.HexToHash("0x005dc005bddd1967de6187c1c23be801eb7abdd80cebcc24f341b727b70311d6")
+	RialtoGenesisHash = common.HexToHash("0xaabe549bfa85c84f7aee9da7010b97453ad686f2c2d8ce00503d1a00c72cad54")
 	YoloV3GenesisHash = common.HexToHash("0xf1f2876e8500c77afcc03228757b39477eceffccf645b734967fe3c7e16967b7")
 	YoloV3GenesisHash = common.HexToHash("0xf1f2876e8500c77afcc03228757b39477eceffccf645b734967fe3c7e16967b7")
 )
 )
 
 
@@ -75,6 +75,7 @@ var (
 		RamanujanBlock:      big.NewInt(0),
 		RamanujanBlock:      big.NewInt(0),
 		NielsBlock:          big.NewInt(0),
 		NielsBlock:          big.NewInt(0),
 		MirrorSyncBlock:     big.NewInt(0),
 		MirrorSyncBlock:     big.NewInt(0),
+		BrunoBlock:          big.NewInt(0),
 		BerlinBlock:         big.NewInt(12_244_000),
 		BerlinBlock:         big.NewInt(12_244_000),
 		Ethash:              new(EthashConfig),
 		Ethash:              new(EthashConfig),
 	}
 	}
@@ -118,6 +119,7 @@ var (
 		RamanujanBlock:      big.NewInt(0),
 		RamanujanBlock:      big.NewInt(0),
 		NielsBlock:          big.NewInt(0),
 		NielsBlock:          big.NewInt(0),
 		MirrorSyncBlock:     big.NewInt(0),
 		MirrorSyncBlock:     big.NewInt(0),
+		BrunoBlock:          big.NewInt(0),
 		BerlinBlock:         big.NewInt(9_812_189),
 		BerlinBlock:         big.NewInt(9_812_189),
 		Ethash:              new(EthashConfig),
 		Ethash:              new(EthashConfig),
 	}
 	}
@@ -161,6 +163,7 @@ var (
 		RamanujanBlock:      big.NewInt(0),
 		RamanujanBlock:      big.NewInt(0),
 		NielsBlock:          big.NewInt(0),
 		NielsBlock:          big.NewInt(0),
 		MirrorSyncBlock:     big.NewInt(0),
 		MirrorSyncBlock:     big.NewInt(0),
+		BrunoBlock:          big.NewInt(0),
 		BerlinBlock:         big.NewInt(8_290_928),
 		BerlinBlock:         big.NewInt(8_290_928),
 		Clique: &CliqueConfig{
 		Clique: &CliqueConfig{
 			Period: 15,
 			Period: 15,
@@ -203,6 +206,7 @@ var (
 		RamanujanBlock:      big.NewInt(0),
 		RamanujanBlock:      big.NewInt(0),
 		NielsBlock:          big.NewInt(0),
 		NielsBlock:          big.NewInt(0),
 		MirrorSyncBlock:     big.NewInt(0),
 		MirrorSyncBlock:     big.NewInt(0),
+		BrunoBlock:          big.NewInt(0),
 		IstanbulBlock:       big.NewInt(1_561_651),
 		IstanbulBlock:       big.NewInt(1_561_651),
 		MuirGlacierBlock:    nil,
 		MuirGlacierBlock:    nil,
 		BerlinBlock:         big.NewInt(4_460_644),
 		BerlinBlock:         big.NewInt(4_460_644),
@@ -246,6 +250,7 @@ var (
 		RamanujanBlock:      big.NewInt(0),
 		RamanujanBlock:      big.NewInt(0),
 		NielsBlock:          big.NewInt(0),
 		NielsBlock:          big.NewInt(0),
 		MirrorSyncBlock:     big.NewInt(5184000),
 		MirrorSyncBlock:     big.NewInt(5184000),
+		BrunoBlock:          nil,
 		Parlia: &ParliaConfig{
 		Parlia: &ParliaConfig{
 			Period: 3,
 			Period: 3,
 			Epoch:  200,
 			Epoch:  200,
@@ -266,6 +271,7 @@ var (
 		RamanujanBlock:      big.NewInt(1010000),
 		RamanujanBlock:      big.NewInt(1010000),
 		NielsBlock:          big.NewInt(1014369),
 		NielsBlock:          big.NewInt(1014369),
 		MirrorSyncBlock:     big.NewInt(5582500),
 		MirrorSyncBlock:     big.NewInt(5582500),
+		BrunoBlock:          big.NewInt(13837000),
 		Parlia: &ParliaConfig{
 		Parlia: &ParliaConfig{
 			Period: 3,
 			Period: 3,
 			Epoch:  200,
 			Epoch:  200,
@@ -286,6 +292,7 @@ var (
 		RamanujanBlock:      big.NewInt(400),
 		RamanujanBlock:      big.NewInt(400),
 		NielsBlock:          big.NewInt(0),
 		NielsBlock:          big.NewInt(0),
 		MirrorSyncBlock:     big.NewInt(400),
 		MirrorSyncBlock:     big.NewInt(400),
+		BrunoBlock:          big.NewInt(400),
 		Parlia: &ParliaConfig{
 		Parlia: &ParliaConfig{
 			Period: 3,
 			Period: 3,
 			Epoch:  200,
 			Epoch:  200,
@@ -308,6 +315,7 @@ var (
 		RamanujanBlock:      big.NewInt(0),
 		RamanujanBlock:      big.NewInt(0),
 		NielsBlock:          big.NewInt(0),
 		NielsBlock:          big.NewInt(0),
 		MirrorSyncBlock:     big.NewInt(0),
 		MirrorSyncBlock:     big.NewInt(0),
+		BrunoBlock:          big.NewInt(0),
 		MuirGlacierBlock:    nil,
 		MuirGlacierBlock:    nil,
 		BerlinBlock:         nil, // Don't enable Berlin directly, we're YOLOing it
 		BerlinBlock:         nil, // Don't enable Berlin directly, we're YOLOing it
 		YoloV3Block:         big.NewInt(0),
 		YoloV3Block:         big.NewInt(0),
@@ -322,16 +330,16 @@ var (
 	//
 	//
 	// This configuration is intentionally not using keyed fields to force anyone
 	// This configuration is intentionally not using keyed fields to force anyone
 	// adding flags to the config to also have to set these fields.
 	// adding flags to the config to also have to set these fields.
-	AllEthashProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, big.NewInt(0), big.NewInt(0), big.NewInt(0), new(EthashConfig), nil, nil}
+	AllEthashProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), new(EthashConfig), nil, nil}
 
 
 	// AllCliqueProtocolChanges contains every protocol change (EIPs) introduced
 	// AllCliqueProtocolChanges contains every protocol change (EIPs) introduced
 	// and accepted by the Ethereum core developers into the Clique consensus.
 	// and accepted by the Ethereum core developers into the Clique consensus.
 	//
 	//
 	// This configuration is intentionally not using keyed fields to force anyone
 	// This configuration is intentionally not using keyed fields to force anyone
 	// adding flags to the config to also have to set these fields.
 	// adding flags to the config to also have to set these fields.
-	AllCliqueProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, &CliqueConfig{Period: 0, Epoch: 30000}, nil}
+	AllCliqueProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, &CliqueConfig{Period: 0, Epoch: 30000}, nil}
 
 
-	TestChainConfig = &ChainConfig{big.NewInt(1), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, big.NewInt(0), big.NewInt(0), big.NewInt(0), new(EthashConfig), nil, nil}
+	TestChainConfig = &ChainConfig{big.NewInt(1), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), new(EthashConfig), nil, nil}
 
 
 	TestRules = TestChainConfig.Rules(new(big.Int))
 	TestRules = TestChainConfig.Rules(new(big.Int))
 )
 )
@@ -418,6 +426,7 @@ type ChainConfig struct {
 	RamanujanBlock  *big.Int `json:"ramanujanBlock,omitempty" toml:",omitempty"`  // ramanujanBlock switch block (nil = no fork, 0 = already activated)
 	RamanujanBlock  *big.Int `json:"ramanujanBlock,omitempty" toml:",omitempty"`  // ramanujanBlock switch block (nil = no fork, 0 = already activated)
 	NielsBlock      *big.Int `json:"nielsBlock,omitempty" toml:",omitempty"`      // nielsBlock switch block (nil = no fork, 0 = already activated)
 	NielsBlock      *big.Int `json:"nielsBlock,omitempty" toml:",omitempty"`      // nielsBlock switch block (nil = no fork, 0 = already activated)
 	MirrorSyncBlock *big.Int `json:"mirrorSyncBlock,omitempty" toml:",omitempty"` // mirrorSyncBlock switch block (nil = no fork, 0 = already activated)
 	MirrorSyncBlock *big.Int `json:"mirrorSyncBlock,omitempty" toml:",omitempty"` // mirrorSyncBlock switch block (nil = no fork, 0 = already activated)
+	BrunoBlock      *big.Int `json:"brunoBlock,omitempty" toml:",omitempty"`      // brunoBlock switch block (nil = no fork, 0 = already activated)
 
 
 	// Various consensus engines
 	// Various consensus engines
 	Ethash *EthashConfig `json:"ethash,omitempty" toml:",omitempty"`
 	Ethash *EthashConfig `json:"ethash,omitempty" toml:",omitempty"`
@@ -468,7 +477,7 @@ func (c *ChainConfig) String() string {
 	default:
 	default:
 		engine = "unknown"
 		engine = "unknown"
 	}
 	}
-	return fmt.Sprintf("{ChainID: %v Homestead: %v DAO: %v DAOSupport: %v EIP150: %v EIP155: %v EIP158: %v Byzantium: %v Constantinople: %v Petersburg: %v Istanbul: %v, Muir Glacier: %v, Ramanujan: %v, Niels: %v, MirrorSync: %v, Berlin: %v, YOLO v3: %v, Engine: %v}",
+	return fmt.Sprintf("{ChainID: %v Homestead: %v DAO: %v DAOSupport: %v EIP150: %v EIP155: %v EIP158: %v Byzantium: %v Constantinople: %v Petersburg: %v Istanbul: %v, Muir Glacier: %v, Ramanujan: %v, Niels: %v, MirrorSync: %v, Bruno: %v, Berlin: %v, YOLO v3: %v, Engine: %v}",
 		c.ChainID,
 		c.ChainID,
 		c.HomesteadBlock,
 		c.HomesteadBlock,
 		c.DAOForkBlock,
 		c.DAOForkBlock,
@@ -484,6 +493,7 @@ func (c *ChainConfig) String() string {
 		c.RamanujanBlock,
 		c.RamanujanBlock,
 		c.NielsBlock,
 		c.NielsBlock,
 		c.MirrorSyncBlock,
 		c.MirrorSyncBlock,
+		c.BrunoBlock,
 		c.BerlinBlock,
 		c.BerlinBlock,
 		c.YoloV3Block,
 		c.YoloV3Block,
 		engine,
 		engine,
@@ -555,6 +565,16 @@ func (c *ChainConfig) IsOnMirrorSync(num *big.Int) bool {
 	return configNumEqual(c.MirrorSyncBlock, num)
 	return configNumEqual(c.MirrorSyncBlock, num)
 }
 }
 
 
+// IsBruno returns whether num is either equal to the Burn fork block or greater.
+func (c *ChainConfig) IsBruno(num *big.Int) bool {
+	return isForked(c.BrunoBlock, num)
+}
+
+// IsOnBruno returns whether num is equal to the Burn fork block
+func (c *ChainConfig) IsOnBruno(num *big.Int) bool {
+	return configNumEqual(c.BrunoBlock, num)
+}
+
 // IsMuirGlacier returns whether num is either equal to the Muir Glacier (EIP-2384) fork block or greater.
 // IsMuirGlacier returns whether num is either equal to the Muir Glacier (EIP-2384) fork block or greater.
 func (c *ChainConfig) IsMuirGlacier(num *big.Int) bool {
 func (c *ChainConfig) IsMuirGlacier(num *big.Int) bool {
 	return isForked(c.MuirGlacierBlock, num)
 	return isForked(c.MuirGlacierBlock, num)
@@ -616,6 +636,7 @@ func (c *ChainConfig) CheckConfigForkOrder() error {
 	var lastFork fork
 	var lastFork fork
 	for _, cur := range []fork{
 	for _, cur := range []fork{
 		{name: "mirrorSyncBlock", block: c.MirrorSyncBlock},
 		{name: "mirrorSyncBlock", block: c.MirrorSyncBlock},
+		{name: "brunoBlock", block: c.BrunoBlock},
 		{name: "berlinBlock", block: c.BerlinBlock},
 		{name: "berlinBlock", block: c.BerlinBlock},
 	} {
 	} {
 		if lastFork.name != "" {
 		if lastFork.name != "" {
@@ -695,6 +716,9 @@ func (c *ChainConfig) checkCompatible(newcfg *ChainConfig, head *big.Int) *Confi
 	if isForkIncompatible(c.MirrorSyncBlock, newcfg.MirrorSyncBlock, head) {
 	if isForkIncompatible(c.MirrorSyncBlock, newcfg.MirrorSyncBlock, head) {
 		return newCompatError("mirrorSync fork block", c.MirrorSyncBlock, newcfg.MirrorSyncBlock)
 		return newCompatError("mirrorSync fork block", c.MirrorSyncBlock, newcfg.MirrorSyncBlock)
 	}
 	}
+	if isForkIncompatible(c.BrunoBlock, newcfg.BrunoBlock, head) {
+		return newCompatError("bruno fork block", c.BrunoBlock, newcfg.BrunoBlock)
+	}
 	return nil
 	return nil
 }
 }
 
 

+ 1 - 1
params/version.go

@@ -23,7 +23,7 @@ import (
 const (
 const (
 	VersionMajor = 1  // Major version component of the current release
 	VersionMajor = 1  // Major version component of the current release
 	VersionMinor = 1  // Minor version component of the current release
 	VersionMinor = 1  // Minor version component of the current release
-	VersionPatch = 3  // Patch version component of the current release
+	VersionPatch = 4  // Patch version component of the current release
 	VersionMeta  = "" // Version metadata to append to the version string
 	VersionMeta  = "" // Version metadata to append to the version string
 )
 )
 
 

برخی فایل ها در این مقایسه diff نمایش داده نمی شوند زیرا تعداد فایل ها بسیار زیاد است