Skip to content

Commit

Permalink
Merge pull request #2179 from PlatONnetwork/feature/bump-version-to-1…
Browse files Browse the repository at this point in the history
….5.0

merge 1.5.0
  • Loading branch information
benbaley authored Oct 30, 2023
2 parents efdaf4f + d7b985f commit 3c9bf7f
Show file tree
Hide file tree
Showing 41 changed files with 387 additions and 316 deletions.
2 changes: 1 addition & 1 deletion accounts/abi/bind/backends/simulated.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ func (b *SimulatedBackend) Commit() {
panic(err) // This cannot happen unless the simulator is wrong, fail in that case
}
stateDB, _ := b.blockchain.State()
b.blockchain.WriteBlockWithState(b.pendingBlock, b.pendingReceipts, nil, stateDB, true)
b.blockchain.WriteBlockWithState(b.pendingBlock, b.pendingReceipts, nil, stateDB, true, nil)
b.rollback()
}

Expand Down
4 changes: 2 additions & 2 deletions cmd/utils/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,11 +126,11 @@ func monitorFreeDiskSpace(sigc chan os.Signal, path string, freeDiskSpaceCritica
break
}
if freeSpace < freeDiskSpaceCritical {
log.Error("Low disk space. Gracefully shutting down Geth to prevent database corruption.", "available", common.StorageSize(freeSpace))
log.Error("Low disk space. Gracefully shutting down PlatON to prevent database corruption.", "available", common.StorageSize(freeSpace))
sigc <- syscall.SIGTERM
break
} else if freeSpace < 2*freeDiskSpaceCritical {
log.Warn("Disk space is running low. Geth will shutdown if disk space runs below critical level.", "available", common.StorageSize(freeSpace), "critical_level", common.StorageSize(freeDiskSpaceCritical))
log.Warn("Disk space is running low. PlatON will shutdown if disk space runs below critical level.", "available", common.StorageSize(freeSpace), "critical_level", common.StorageSize(freeDiskSpaceCritical))
}
time.Sleep(60 * time.Second)
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/utils/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -1353,7 +1353,7 @@ func RegisterEthService(stack *node.Node, cfg *ethconfig.Config) ethapi.Backend
} else {
backend, err := eth.New(stack, cfg)
if err != nil {
Fatalf("Failed to register the Ethereum service: %v", err)
Fatalf("Failed to register the PlatON service: %v", err)
}
stack.RegisterAPIs(tracers.APIs(backend.APIBackend))
return backend.APIBackend
Expand Down
1 change: 1 addition & 0 deletions common/vm/inner_contract.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ var (
DelegateRewardPoolAddr = common.HexToAddress("0x1000000000000000000000000000000000000006") // The PlatON Precompiled contract addr for delegate reward
ValidatorInnerContractAddr = common.HexToAddress("0x2000000000000000000000000000000000000000") // The PlatON Precompiled contract addr for cbft inner
VrfInnerContractAddr = common.HexToAddress("0x3000000000000000000000000000000000000001") // The PlatON Precompiled contract addr for vrf inner
BlsVerifyContractAddr = common.HexToAddress("0x3000000000000000000000000000000000000002") // The PlatON Precompiled contract addr for bls verify
)

type PrecompiledContractCheck interface {
Expand Down
60 changes: 4 additions & 56 deletions consensus/bft_mock.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ func (bm *BftMock) Author(header *types.Header) (common.Address, error) {
// VerifyHeader checks whether a header conforms to the consensus rules of a
// given engine. Verifying the seal may be done optionally here, or explicitly
// via the VerifySeal method.
func (bm *BftMock) VerifyHeader(chain ChainReader, header *types.Header, seal bool) error {
func (bm *BftMock) VerifyHeader(chain ChainReader, header *types.Header, async bool) error {
if bm.fakeFail == header.Number.Uint64() {
return fmt.Errorf("failed verifyHeader on bftMock")
}
Expand Down Expand Up @@ -292,48 +292,11 @@ func (bm *BftMock) ShouldSeal(curTime time.Time) (bool, error) {
return true, nil
}

// OnBlockSignature received a new block signature
// Need to verify if the signature is signed by nodeID
func (bm *BftMock) OnBlockSignature(chain ChainReader, nodeID enode.IDv0, sig *cbfttypes.BlockSignature) error {
return nil
}

// OnNewBlock processes the BFT signatures
func (bm *BftMock) OnNewBlock(chain ChainReader, block *types.Block) error {
return nil
}

// OnPong processes the BFT signatures
func (bm *BftMock) OnPong(nodeID enode.IDv0, netLatency int64) error {
return nil

}

// OnBlockSynced sends a signal if a block synced from other peer.
func (bm *BftMock) OnBlockSynced() {

}

// CheckConsensusNode is a fake interface, no need to implement.
func (bm *BftMock) CheckConsensusNode(nodeID enode.IDv0) (bool, error) {
return true, nil
}

// IsConsensusNode is a fake interface, no need to implement.
func (bm *BftMock) IsConsensusNode() bool {
return true
}

// HighestLogicalBlock is a fake interface, no need to implement.
func (bm *BftMock) HighestLogicalBlock() *types.Block {
return nil
}

// HighestConfirmedBlock is a fake interface, no need to implement.
func (bm *BftMock) HighestConfirmedBlock() *types.Block {
return nil
}

// GetBlock is a fake interface, no need to implement.
func (bm *BftMock) GetBlock(hash common.Hash, number uint64) *types.Block {
return nil
Expand Down Expand Up @@ -364,32 +327,17 @@ func (bm *BftMock) GetBlockByHashAndNum(hash common.Hash, number uint64) *types.
return nil
}

// Status is a fake interface, no need to implement.
func (bm *BftMock) Status() string {
return ""
}

// CurrentBlock is a fake interface, no need to implement.
func (bm *BftMock) CurrentBlock() *types.Block {
//if len(bm.Blocks) == 0 {
// h := types.Header{Number: big.NewInt(0)}
// return types.NewBlockWithHeader(&h)
//}
//return bm.Blocks[len(bm.Blocks)-1]
return bm.Current
}

// TracingSwitch is a fake interface, no need to implement.
func (bm *BftMock) TracingSwitch(flag int8) {

}
func (bm *BftMock) TracingSwitch(flag int8) {}

func (bm *BftMock) Pause() {
func (bm *BftMock) Pause() {}

}
func (bm *BftMock) Resume() {

}
func (bm *BftMock) Resume() {}

func (bm *BftMock) Syncing() bool {
return false
Expand Down
32 changes: 28 additions & 4 deletions consensus/cbft/cbft.go
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@ func (cbft *Cbft) ReceiveMessage(msg *ctypes.MsgInfo) error {

cMsg := msg.Msg.(ctypes.ConsensusMsg)
if invalidMsg(cMsg.EpochNum(), cMsg.ViewNum()) {
cbft.log.Debug("Invalid msg", "peer", msg.PeerID, "type", reflect.TypeOf(msg.Msg), "msg", msg.Msg.String())
cbft.log.Trace("Invalid msg", "peer", msg.PeerID, "type", reflect.TypeOf(msg.Msg), "msg", msg.Msg.String())
return nil
}

Expand Down Expand Up @@ -641,7 +641,7 @@ func (cbft *Cbft) Author(header *types.Header) (common.Address, error) {
return header.Coinbase, nil
}

func (cbft *Cbft) VerifyHeader(chain consensus.ChainReader, header *types.Header, seal bool) error {
func (cbft *Cbft) VerifyHeader(chain consensus.ChainReader, header *types.Header, async bool) error {
// Short circuit if the header is known, or its parent not
number := header.Number.Uint64()
if chain.GetHeader(header.Hash(), number) != nil {
Expand All @@ -650,7 +650,12 @@ func (cbft *Cbft) VerifyHeader(chain consensus.ChainReader, header *types.Header

parent := chain.GetHeader(header.ParentHash, number-1)
if parent == nil {
parentBlock := cbft.GetBlockWithoutLock(header.ParentHash, number-1)
var parentBlock *types.Block
if async {
parentBlock = cbft.GetBlockWithLock(header.ParentHash, number-1)
} else {
parentBlock = cbft.GetBlockWithoutLock(header.ParentHash, number-1)
}
if parentBlock != nil {
parent = parentBlock.Header()
}
Expand Down Expand Up @@ -738,7 +743,7 @@ func (cbft *Cbft) verifyHeaderWorker(chain consensus.ChainReader, headers []*typ
if index == 0 {
parent = chain.GetHeader(headers[0].ParentHash, headers[0].Number.Uint64()-1)
if parent == nil {
parentBlock := cbft.GetBlockWithoutLock(headers[0].ParentHash, headers[0].Number.Uint64()-1)
parentBlock := cbft.GetBlockWithLock(headers[0].ParentHash, headers[0].Number.Uint64()-1)
if parentBlock != nil {
parent = parentBlock.Header()
}
Expand Down Expand Up @@ -1312,6 +1317,25 @@ func (cbft *Cbft) GetBlock(hash common.Hash, number uint64) *types.Block {
return <-result
}

// GetBlockWithLock synchronously obtains blocks according to the specified number and hash.
func (cbft *Cbft) GetBlockWithLock(hash common.Hash, number uint64) *types.Block {
result := make(chan *types.Block, 1)

cbft.asyncCallCh <- func() {
block, _ := cbft.blockTree.FindBlockAndQC(hash, number)
if block == nil {
if eb := cbft.state.FindBlock(hash, number); eb != nil {
block = eb
} else {
cbft.log.Debug("Get block failed", "hash", hash, "number", number)
}
}
result <- block
}

return <-result
}

// GetBlockWithoutLock returns the block corresponding to the specified number and hash.
func (cbft *Cbft) GetBlockWithoutLock(hash common.Hash, number uint64) *types.Block {
block, _ := cbft.blockTree.FindBlockAndQC(hash, number)
Expand Down
2 changes: 1 addition & 1 deletion consensus/cbft/sync_process.go
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ func (cbft *Cbft) prepareVoteFetchRules(id string, vote *protocols.PrepareVote)
func (cbft *Cbft) OnGetPrepareBlock(id string, msg *protocols.GetPrepareBlock) error {
if msg.Epoch == cbft.state.Epoch() && msg.ViewNumber == cbft.state.ViewNumber() {
prepareBlock := cbft.state.PrepareBlockByIndex(msg.BlockIndex)
if prepareBlock != nil {
if prepareBlock != nil && prepareBlock.Signature.NotEmpty() {
cbft.log.Debug("Send PrepareBlock", "peer", id, "prepareBlock", prepareBlock.String())
cbft.network.Send(id, prepareBlock)
}
Expand Down
7 changes: 6 additions & 1 deletion consensus/cbft/types/crypto.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@
// You should have received a copy of the GNU Lesser General Public License
// along with the PlatON-Go library. If not, see <http://www.gnu.org/licenses/>.


package types

import (
"bytes"
"fmt"
"reflect"

Expand Down Expand Up @@ -48,6 +48,11 @@ func (sig *Signature) Bytes() []byte {
return target
}

func (sig *Signature) NotEmpty() bool {
var a Signature
return bytes.Compare(sig.Bytes(), a.Bytes()) != 0
}

// MarshalText returns the hex representation of a.
func (sig Signature) MarshalText() ([]byte, error) {
return hexutil.Bytes(sig[:]).MarshalText()
Expand Down
10 changes: 9 additions & 1 deletion consensus/cbft/types/crypto_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
// You should have received a copy of the GNU Lesser General Public License
// along with the PlatON-Go library. If not, see <http://www.gnu.org/licenses/>.


package types

import (
Expand Down Expand Up @@ -106,3 +105,12 @@ func Test_ViewChangeQC_MaxBlock(t *testing.T) {
epoch, viewNumber, blockEpoch, blockViewNumber, blockHash, blockNumber = viewChangeQC.MaxBlock()
assert.Equal(t, uint64(0), epoch)
}

func Test_Signature_NotEmpty(t *testing.T) {
var sig Signature
assert.False(t, sig.NotEmpty())
sig = Signature{byte(0), byte(0), byte(0)}
assert.False(t, sig.NotEmpty())
sig = Signature{byte(0), byte(0), byte(1)}
assert.True(t, sig.NotEmpty())
}
6 changes: 6 additions & 0 deletions consensus/cbft/validator/validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,12 @@ func (vp *ValidatorPool) Update(blockNumber uint64, epoch uint64, eventMux *even

isValidatorAfter := vp.isValidator(epoch, vp.nodeID)

nodes := make(map[enode.ID]struct{})
for _, validator := range vp.currentValidators.Nodes {
nodes[validator.NodeID] = struct{}{}
}
eventMux.Post(cbfttypes.UpdateValidatorEvent{Nodes: nodes})

if isValidatorBefore {
// If we are still a consensus node, that adding
// new validators as consensus peer, and removing
Expand Down
2 changes: 1 addition & 1 deletion consensus/consensus.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ type Engine interface {
// VerifyHeader checks whether a header conforms to the consensus rules of a
// given engine. Verifying the seal may be done optionally here, or explicitly
// via the VerifySeal method.
VerifyHeader(chain ChainReader, header *types.Header, seal bool) error
VerifyHeader(chain ChainReader, header *types.Header, async bool) error

// VerifyHeaders is similar to VerifyHeader, but verifies a batch of headers
// concurrently. The method returns a quit channel to abort the operations and
Expand Down
69 changes: 39 additions & 30 deletions core/blockchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -325,30 +325,34 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, chainConfig *par
// Make sure the state associated with the block is available
head := bc.CurrentBlock()
if _, err := state.New(head.Root(), bc.stateCache, bc.snaps); err != nil {
// Head state is missing, before the state recovery, find out the
// disk layer point of snapshot(if it's enabled). Make sure the
// rewound point is lower than disk layer.
var diskRoot common.Hash
if bc.cacheConfig.SnapshotLimit > 0 {
diskRoot = rawdb.ReadSnapshotRoot(bc.db)
}
if diskRoot != (common.Hash{}) {
log.Warn("Head state missing, repairing", "number", head.Number(), "hash", head.Hash(), "snaproot", diskRoot)

snapDisk, err := bc.setHeadBeyondRoot(head.NumberU64(), diskRoot, true)
if err != nil {
return nil, err
log.Warn("Head state missing, repair not supported", "number", head.NumberU64(), "hash", head.Hash().String())
return nil, fmt.Errorf("head state missing, repair not supported, number:%d, hash:%s", head.NumberU64(), head.Hash().String())
/*
// Head state is missing, before the state recovery, find out the
// disk layer point of snapshot(if it's enabled). Make sure the
// rewound point is lower than disk layer.
var diskRoot common.Hash
if bc.cacheConfig.SnapshotLimit > 0 {
diskRoot = rawdb.ReadSnapshotRoot(bc.db)
}
// Chain rewound, persist old snapshot number to indicate recovery procedure
if snapDisk != 0 {
rawdb.WriteSnapshotRecoveryNumber(bc.db, snapDisk)
}
} else {
log.Warn("Head state missing, repairing", "number", head.Number(), "hash", head.Hash())
if _, err := bc.setHeadBeyondRoot(head.NumberU64(), common.Hash{}, true); err != nil {
return nil, err
if diskRoot != (common.Hash{}) {
log.Warn("Head state missing, repairing", "number", head.Number(), "hash", head.Hash(), "snaproot", diskRoot)
snapDisk, err := bc.setHeadBeyondRoot(head.NumberU64(), diskRoot, true)
if err != nil {
return nil, err
}
// Chain rewound, persist old snapshot number to indicate recovery procedure
if snapDisk != 0 {
rawdb.WriteSnapshotRecoveryNumber(bc.db, snapDisk)
}
} else {
log.Warn("Head state missing, repairing", "number", head.Number(), "hash", head.Hash())
if _, err := bc.setHeadBeyondRoot(head.NumberU64(), common.Hash{}, true); err != nil {
return nil, err
}
}
}
*/
}

// Ensure that a previous crash in SetHead doesn't leave extra ancients
Expand Down Expand Up @@ -399,10 +403,11 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, chainConfig *par
var recover bool

head := bc.CurrentBlock()
if layer := rawdb.ReadSnapshotRecoveryNumber(bc.db); layer != nil && *layer > head.NumberU64() {
log.Warn("Enabling snapshot recovery", "chainhead", head.NumberU64(), "diskbase", *layer)
recover = true
}
// Repair not supported
//if layer := rawdb.ReadSnapshotRecoveryNumber(bc.db); layer != nil && *layer > head.NumberU64() {
// log.Warn("Enabling snapshot recovery", "chainhead", head.NumberU64(), "diskbase", *layer)
// recover = true
//}
bc.snaps, _ = snapshot.New(bc.db, bc.stateCache.TrieDB(), bc.cacheConfig.SnapshotLimit, head.Root(), !bc.cacheConfig.SnapshotWait, true, recover)
}

Expand Down Expand Up @@ -1247,11 +1252,14 @@ func (bc *BlockChain) WriteBlockWithoutState(block *types.Block) (err error) {
}

// WriteBlockWithState writes the block and all associated state to the database.
func (bc *BlockChain) WriteBlockWithState(block *types.Block, receipts []*types.Receipt, logs []*types.Log, state *state.StateDB, emitHeadEvent bool) (status WriteStatus, err error) {
func (bc *BlockChain) WriteBlockWithState(block *types.Block, receipts []*types.Receipt, logs []*types.Log, state *state.StateDB, emitHeadEvent bool, cbftBridgeUpdateChainState func()) (status WriteStatus, err error) {
if !bc.chainmu.TryLock() {
return NonStatTy, errInsertionInterrupted
}
defer bc.chainmu.Unlock()
if cbftBridgeUpdateChainState != nil {
cbftBridgeUpdateChainState()
}
return bc.writeBlockWithState(block, receipts, logs, state, emitHeadEvent)
}

Expand Down Expand Up @@ -1530,13 +1538,14 @@ func (bc *BlockChain) insertChain(chain types.Blocks, verifySeals bool) (int, er
headers[i] = block.Header()
seals[i] = verifySeals
}
abort, results := bc.engine.VerifyHeaders(bc, headers, seals)
defer close(abort)

// Pause engine
bc.engine.Pause()
defer bc.engine.Resume()

abort, results := bc.engine.VerifyHeaders(bc, headers, seals)
defer close(abort)

// Peek the error for the first block to decide the directing import logic
it := newInsertIterator(chain, results, bc.Validator())
block, err := it.next()
Expand All @@ -1561,7 +1570,7 @@ func (bc *BlockChain) insertChain(chain types.Blocks, verifySeals bool) (int, er
return it.index, err
}
// No validation errors for the first block (or chain prefix skipped)
for ; block != nil && err == nil; block, err = it.next() {
for ; block != nil && (err == nil || errors.Is(err, ErrKnownBlock)); block, err = it.next() {
// If the chain is terminating, stop processing blocks
if bc.insertStopped() {
log.Debug("Abort during block processing")
Expand Down
Loading

0 comments on commit 3c9bf7f

Please sign in to comment.