aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbojie <bojie@dexon.org>2018-12-05 00:29:53 +0800
committerWei-Ning Huang <w@dexon.org>2019-04-09 21:32:54 +0800
commitfc03a1af7bc59530681ed7d9b1daf12c1fca902c (patch)
treee833dc1aec1c679512c1916ba14580a71a7a6e09
parentdbdeb63000ae5626806432137799d560e19d33d0 (diff)
downloadgo-tangerine-fc03a1af7bc59530681ed7d9b1daf12c1fca902c.tar
go-tangerine-fc03a1af7bc59530681ed7d9b1daf12c1fca902c.tar.gz
go-tangerine-fc03a1af7bc59530681ed7d9b1daf12c1fca902c.tar.bz2
go-tangerine-fc03a1af7bc59530681ed7d9b1daf12c1fca902c.tar.lz
go-tangerine-fc03a1af7bc59530681ed7d9b1daf12c1fca902c.tar.xz
go-tangerine-fc03a1af7bc59530681ed7d9b1daf12c1fca902c.tar.zst
go-tangerine-fc03a1af7bc59530681ed7d9b1daf12c1fca902c.zip
app: misc fixes (#76)
Use sync map to prevent concurrent read write. Use last pending state to prepare/verify transactions.
-rw-r--r--dex/app.go80
1 files changed, 30 insertions, 50 deletions
diff --git a/dex/app.go b/dex/app.go
index eae9ba0b3..8723420c5 100644
--- a/dex/app.go
+++ b/dex/app.go
@@ -47,9 +47,7 @@ type DexconApp struct {
chainDB ethdb.Database
config *Config
- chainLocksInitMu sync.Mutex
- chainLocks map[uint32]*sync.RWMutex
-
+ chainLocks sync.Map
chainLatestRoot sync.Map
}
@@ -67,7 +65,6 @@ func NewDexconApp(txPool *core.TxPool, blockchain *core.BlockChain, gov *DexconG
gov: gov,
chainDB: chainDB,
config: config,
- chainLocks: make(map[uint32]*sync.RWMutex),
}
}
@@ -75,32 +72,38 @@ func (d *DexconApp) addrBelongsToChain(address common.Address, chainSize, chainI
return new(big.Int).Mod(address.Big(), chainSize).Cmp(chainID) == 0
}
-func (d *DexconApp) chainLockInit(chainID uint32) {
- d.chainLocksInitMu.Lock()
- defer d.chainLocksInitMu.Unlock()
-
- _, exist := d.chainLocks[chainID]
- if !exist {
- d.chainLocks[chainID] = &sync.RWMutex{}
- }
-}
-
func (d *DexconApp) chainLock(chainID uint32) {
- d.chainLockInit(chainID)
- d.chainLocks[chainID].Lock()
+ v, ok := d.chainLocks.Load(chainID)
+ if !ok {
+ v = &sync.RWMutex{}
+ d.chainLocks.Store(chainID, v)
+ }
+ v.(*sync.RWMutex).Lock()
}
func (d *DexconApp) chainUnlock(chainID uint32) {
- d.chainLocks[chainID].Unlock()
+ v, ok := d.chainLocks.Load(chainID)
+ if !ok {
+ panic(fmt.Errorf("chain %v is not init yet", chainID))
+ }
+ v.(*sync.RWMutex).Unlock()
}
func (d *DexconApp) chainRLock(chainID uint32) {
- d.chainLockInit(chainID)
- d.chainLocks[chainID].RLock()
+ v, ok := d.chainLocks.Load(chainID)
+ if !ok {
+ v = &sync.RWMutex{}
+ d.chainLocks.Store(chainID, v)
+ }
+ v.(*sync.RWMutex).RLock()
}
func (d *DexconApp) chainRUnlock(chainID uint32) {
- d.chainLocks[chainID].RUnlock()
+ v, ok := d.chainLocks.Load(chainID)
+ if !ok {
+ panic(fmt.Errorf("chain %v is not init yet", chainID))
+ }
+ v.(*sync.RWMutex).RUnlock()
}
// validateNonce check if nonce is in order and return first nonce of every address.
@@ -189,21 +192,9 @@ func (d *DexconApp) preparePayload(ctx context.Context, position coreTypes.Posit
}
}
- var root *common.Hash
- value, ok := d.chainLatestRoot.Load(position.ChainID)
- if ok {
- root = value.(*common.Hash)
- } else {
- currentRoot := d.blockchain.CurrentBlock().Root()
- root = &currentRoot
- }
-
- // Set state to the chain latest height.
- latestState, err := d.blockchain.StateAt(*root)
- if err != nil {
- log.Error("Get pending state", "error", err)
- return nil, fmt.Errorf("get pending state error: %v", err)
- }
+ b, latestState := d.blockchain.GetPending()
+ log.Debug("Prepare payload", "chain", position.ChainID, "height", position.Height, "state",
+ b.Root().String())
txsMap, err := d.txPool.Pending()
if err != nil {
@@ -367,21 +358,10 @@ func (d *DexconApp) VerifyBlock(block *coreTypes.Block) coreTypes.BlockVerifySta
}
}
- // Find the latest state for the given block height.
- var root *common.Hash
- value, ok := d.chainLatestRoot.Load(block.Position.ChainID)
- if ok {
- root = value.(*common.Hash)
- } else {
- currentRoot := d.blockchain.CurrentBlock().Root()
- root = &currentRoot
- }
-
- latestState, err := d.blockchain.StateAt(*root)
- if err != nil {
- log.Error("Failed to get pending state", "error", err)
- return coreTypes.VerifyInvalidBlock
- }
+ // Get latest pending state.
+ b, latestState := d.blockchain.GetPending()
+ log.Debug("Verify block", "chain", block.Position.ChainID, "height", block.Position.Height, "state",
+ b.Root().String())
var transactions types.Transactions
if len(block.Payload) == 0 {