Skip to content

Commit

Permalink
Merge pull request #550 from binance-chain/develop
Browse files Browse the repository at this point in the history
Release v1.1.5
  • Loading branch information
yutianwu committed Nov 16, 2021
2 parents db2eea7 + 6fb789d commit 8ff7d53
Show file tree
Hide file tree
Showing 7 changed files with 71 additions and 26 deletions.
9 changes: 9 additions & 0 deletions CHANGELOG.md
@@ -1,4 +1,13 @@
# Changelog
## v1.1.5
BUGFIX
* [\#509](https://github.com/binance-chain/bsc/pull/509) fix graceful shutdown bug

IMPROVEMENT
* [\#536](https://github.com/binance-chain/bsc/pull/536) get diff accounts by replaying block when diff layer not found
* [\#527](https://github.com/binance-chain/bsc/pull/527) improve diffsync protocol in many aspects
* [\#493](https://github.com/binance-chain/bsc/pull/493) implement fast getDiffAccountsWithScope API

## v1.1.4
Improvement
* [\#472](https://github.com/binance-chain/bsc/pull/472) add metrics for contract code bitmap cache
Expand Down
2 changes: 1 addition & 1 deletion core/blockchain.go
Expand Up @@ -1011,7 +1011,7 @@ func (bc *BlockChain) GetDiffAccounts(blockHash common.Hash) ([]common.Address,

if diffLayer == nil {
if header.TxHash != types.EmptyRootHash {
return nil, fmt.Errorf("no diff layer found")
return nil, ErrDiffLayerNotFound
}

return nil, nil
Expand Down
3 changes: 3 additions & 0 deletions core/error.go
Expand Up @@ -31,6 +31,9 @@ var (

// ErrNoGenesis is returned when there is no Genesis Block.
ErrNoGenesis = errors.New("genesis not found in chain")

// ErrDiffLayerNotFound is returned when diff layer not found.
ErrDiffLayerNotFound = errors.New("diff layer not found")
)

// List of evm-call-message pre-checking errors. All state transition messages will
Expand Down
8 changes: 8 additions & 0 deletions core/state/statedb.go
Expand Up @@ -1493,3 +1493,11 @@ func (s *StateDB) SlotInAccessList(addr common.Address, slot common.Hash) (addre
}
return s.accessList.Contains(addr, slot)
}

func (s *StateDB) GetDirtyAccounts() []common.Address {
accounts := make([]common.Address, 0, len(s.stateObjectsDirty))
for account := range s.stateObjectsDirty {
accounts = append(accounts, account)
}
return accounts
}
71 changes: 48 additions & 23 deletions internal/ethapi/api.go
Expand Up @@ -1098,7 +1098,21 @@ func (s *PublicBlockChainAPI) GetDiffAccounts(ctx context.Context, blockNr rpc.B
return nil, fmt.Errorf("block not found for block number (%d): %v", blockNr, err)
}

return s.b.Chain().GetDiffAccounts(header.Hash())
accounts, err := s.b.Chain().GetDiffAccounts(header.Hash())
if err == nil || !errors.Is(err, core.ErrDiffLayerNotFound) {
return accounts, err
}

// Replay the block when diff layer not found, it is very slow.
block, err := s.b.BlockByNumber(ctx, blockNr)
if err != nil {
return nil, fmt.Errorf("block not found for block number (%d): %v", blockNr, err)
}
_, statedb, err := s.replay(ctx, block, nil)
if err != nil {
return nil, err
}
return statedb.GetDirtyAccounts(), nil
}

func (s *PublicBlockChainAPI) needToReplay(ctx context.Context, block *types.Block, accounts []common.Address) (bool, error) {
Expand Down Expand Up @@ -1161,36 +1175,20 @@ func (s *PublicBlockChainAPI) needToReplay(ctx context.Context, block *types.Blo
return false, nil
}

// GetDiffAccountsWithScope returns detailed changes of some interested accounts in a specific block number.
func (s *PublicBlockChainAPI) GetDiffAccountsWithScope(ctx context.Context, blockNr rpc.BlockNumber, accounts []common.Address) (*types.DiffAccountsInBlock, error) {
if s.b.Chain() == nil {
return nil, fmt.Errorf("blockchain not support get diff accounts")
}

block, err := s.b.BlockByNumber(ctx, blockNr)
if err != nil {
return nil, fmt.Errorf("block not found for block number (%d): %v", blockNr, err)
}

func (s *PublicBlockChainAPI) replay(ctx context.Context, block *types.Block, accounts []common.Address) (*types.DiffAccountsInBlock, *state.StateDB, error) {
result := &types.DiffAccountsInBlock{
Number: uint64(blockNr),
Number: block.NumberU64(),
BlockHash: block.Hash(),
Transactions: make([]types.DiffAccountsInTx, 0),
}

if needReplay, err := s.needToReplay(ctx, block, accounts); err != nil {
return nil, err
} else if !needReplay {
return result, nil
}

parent, err := s.b.BlockByHash(ctx, block.ParentHash())
if err != nil {
return nil, fmt.Errorf("block not found for block number (%d): %v", blockNr-1, err)
return nil, nil, fmt.Errorf("block not found for block number (%d): %v", block.NumberU64()-1, err)
}
statedb, err := s.b.Chain().StateAt(parent.Root())
if err != nil {
return nil, fmt.Errorf("state not found for block number (%d): %v", blockNr-1, err)
return nil, nil, fmt.Errorf("state not found for block number (%d): %v", block.NumberU64()-1, err)
}

accountSet := make(map[common.Address]struct{}, len(accounts))
Expand Down Expand Up @@ -1240,7 +1238,7 @@ func (s *PublicBlockChainAPI) GetDiffAccountsWithScope(ctx context.Context, bloc
}

if _, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(tx.Gas())); err != nil {
return nil, fmt.Errorf("transaction %#x failed: %v", tx.Hash(), err)
return nil, nil, fmt.Errorf("transaction %#x failed: %v", tx.Hash(), err)
}
statedb.Finalise(vmenv.ChainConfig().IsEIP158(block.Number()))

Expand All @@ -1259,7 +1257,34 @@ func (s *PublicBlockChainAPI) GetDiffAccountsWithScope(ctx context.Context, bloc
}
}

return result, nil
return result, statedb, nil
}

// GetDiffAccountsWithScope returns detailed changes of some interested accounts in a specific block number.
func (s *PublicBlockChainAPI) GetDiffAccountsWithScope(ctx context.Context, blockNr rpc.BlockNumber, accounts []common.Address) (*types.DiffAccountsInBlock, error) {
if s.b.Chain() == nil {
return nil, fmt.Errorf("blockchain not support get diff accounts")
}

block, err := s.b.BlockByNumber(ctx, blockNr)
if err != nil {
return nil, fmt.Errorf("block not found for block number (%d): %v", blockNr, err)
}

needReplay, err := s.needToReplay(ctx, block, accounts)
if err != nil {
return nil, err
}
if !needReplay {
return &types.DiffAccountsInBlock{
Number: uint64(blockNr),
BlockHash: block.Hash(),
Transactions: make([]types.DiffAccountsInTx, 0),
}, nil
}

result, _, err := s.replay(ctx, block, accounts)
return result, err
}

// ExecutionResult groups all structured logs emitted by the EVM
Expand Down
2 changes: 1 addition & 1 deletion params/config.go
Expand Up @@ -250,7 +250,7 @@ var (
RamanujanBlock: big.NewInt(0),
NielsBlock: big.NewInt(0),
MirrorSyncBlock: big.NewInt(5184000),
BrunoBlock: nil,
BrunoBlock: big.NewInt(13082000),
Parlia: &ParliaConfig{
Period: 3,
Epoch: 200,
Expand Down
2 changes: 1 addition & 1 deletion params/version.go
Expand Up @@ -23,7 +23,7 @@ import (
const (
VersionMajor = 1 // Major version component of the current release
VersionMinor = 1 // Minor version component of the current release
VersionPatch = 4 // Patch version component of the current release
VersionPatch = 5 // Patch version component of the current release
VersionMeta = "" // Version metadata to append to the version string
)

Expand Down

0 comments on commit 8ff7d53

Please sign in to comment.