GithubHelp home page GithubHelp logo

chain's Introduction

chain's People

Contributors

dwymi02 avatar hacashcom avatar

Watchers

 avatar  avatar

Forkers

dwymi02 seenhit

chain's Issues

Summary of Data Races associated with [*ChainState]

Summary of Data Races associated with [*ChainState]

  • Text file of instrumented Diamond Miner [DiamondMiner_log_Sep_21_2021.txt], available via Github Gist [https://gist.github.com/dwymi02/95140687b566efa22939dec3cd14dd6d]

  • The instrumented binary was built from refreshed code, dated Sep-21-2021.
    The source code repository was wiped clean and "git clone ..." was used to create the updated code base.

  • The instrumented code was built with "-race", e.g., "go build -race".

  • The directory [hacash_mainnet_data/] was completely removed, to allow the Hacash blockchain to be built from scratch, also allowing for additional Data Races to be uncovered, if any.

  • In searching for Data Races I tried to group them based on specific Hacash components.
    Grep was used to search for known Hacash components, following is a list of potential Data Races, based on Hacash components:

    • A search for [*P2P] returned 109 hits
    • A search for [*Block_v1] returned 4 hits
    • A search for [*ChainState] returned 3 hits
    • A search for [*DiamondMiner] returned 45 hits
    • A search for [*DeprecatedApiService] returned 33 hits
    • A search for [*Transaction_2_Simple] returned 14 hits
      While there are large numbers of potential hits, there Hacash components may or may not be proximate to the actual Data Race.

    For each Hacash component I will list the specific Data Race.
    When the current code does not match what was previously built, a [*** NOTE ***] will be included
    In the event the stack trace that is too lengthy, the results will be truncated.
    If it is necessary, the full log will be provided, as needed.

    For the specific Read and Write that are involved in the Data Race, the [<===] will be used to identify where the specific Read/Write occurred, based on current source available ...

    Once the Data Race has been documented, an issue will be opened on Github.
    I will leave it to your team to decide how the Data Race is to be handled.
    You can opt to fix the Data Race or simply close the issue. as you so choose.
    This decision I leave with you and your team ...

=-=-=-=-=-=-=-=-=-=-=-=-=-

Data Races associated with [*ChainState]

  • ChainState Data Race # 1:
    [Peer] HacPool (3.101.62.234:3337) id:9916d846b996b95eace30b76d6af3e0b connect.
    [Peer] WoW_0527_II (104.217.254.247:3337) id:5d806a7143dba02100f11422397c8f5a connect.
    [Peer] hn_7c5b248c59 (54.149.141.75:4447) id:7c5b248c5965ce1dd79666e19ee8228f connect.

    WARNING: DATA RACE
    Read at 0x00c4200fa428 by goroutine 53:
    chain/chainstatev2.(*ChainState).ReadLastestDiamond()
    chain/chainstatev2/last_status.go:121 +0x95
    miner/diamondminer.(*DiamondMiner).Start.func1()
    miner/diamondminer/miner.go:56 +0x92

    Previous write at 0x00c4200fa428 by goroutine 63:
    chain/chainstatev2.(*ChainState).ReadLastestDiamond()
    chain/chainstatev2/last_status.go:151 +0x393
    mint/blockchain.(*BlockChain).ValidateDiamondCreateAction()
    mint/blockchain/validatediamond.go:25 +0xd5
    miner/memtxpool.(*MemTxPool).checkDiamondCreate()
    miner/memtxpool/check.go:50 +0x78c
    miner/memtxpool.(*MemTxPool).AddTx()
    miner/memtxpool/add.go:94 +0x51c
    node/handler.GetTransactionSubmit()
    node/handler/newtxblock.go:94 +0x1c3
    node/backend.(*Backend).OnMsgData()
    node/backend/message.go:67 +0x28d
    node/p2pv2.(*P2P).handleConnMsg()
    node/p2pv2/tcp_msg_handler.go:39 +0x8f5

    Read:
    [chain/chainstatev2/last_status.go:121]
    func (cs *ChainState) ReadLastestDiamond() (*stores.DiamondSmelt, error) {
    //fmt.Println("ReadLastestDiamond >>>>>>>")
    cs.chainStateMutex.RLock()
    if cs.lastestDiamond != nil { <=== Read
    defer cs.chainStateMutex.RUnlock()
    return cs.lastestDiamond, nil
    }
    if cs.base != nil {
    defer cs.chainStateMutex.RUnlock()
    return cs.base.ReadLastestDiamond()
    }
    cs.chainStateMutex.RUnlock()
    // read from status db
    //fmt.Println("ReadLastestDiamond >>>>>>> read from status db")
    vdatas, e3 := cs.laststatusDB.Get([]byte(LastestStatusKeyName_lastest_diamond))
    if e3 != nil {
    return nil, e3
    }
    // check
    if vdatas == nil {
    //fmt.Println("ReadLastestDiamond return nil, nil // first one")
    return nil, nil // first one
    }
    if len(vdatas) == 0 {
    return nil, fmt.Errorf("lastest_diamond store file error.")
    }
    var diamond stores.DiamondSmelt
    _, err := diamond.Parse(vdatas, 0)
    if err != nil {
    return nil, err
    }
    // cache set
    //fmt.Println("ReadLastestDiamond ", diamond)
    cs.lastestDiamond = &diamond
    return &diamond, nil

    }

    Write:
    [chain/chainstatev2/last_status.go:151]
    func (cs *ChainState) ReadLastestDiamond() (*stores.DiamondSmelt, error) {
    //fmt.Println("ReadLastestDiamond >>>>>>>")
    cs.chainStateMutex.RLock()
    if cs.lastestDiamond != nil {
    defer cs.chainStateMutex.RUnlock()
    return cs.lastestDiamond, nil
    }
    if cs.base != nil {
    defer cs.chainStateMutex.RUnlock()
    return cs.base.ReadLastestDiamond()
    }
    cs.chainStateMutex.RUnlock()
    // read from status db
    //fmt.Println("ReadLastestDiamond >>>>>>> read from status db")
    vdatas, e3 := cs.laststatusDB.Get([]byte(LastestStatusKeyName_lastest_diamond))
    if e3 != nil {
    return nil, e3
    }
    // check
    if vdatas == nil {
    //fmt.Println("ReadLastestDiamond return nil, nil // first one")
    return nil, nil // first one
    }
    if len(vdatas) == 0 {
    return nil, fmt.Errorf("lastest_diamond store file error.")
    }
    var diamond stores.DiamondSmelt
    _, err := diamond.Parse(vdatas, 0)
    if err != nil {
    return nil, err
    }
    // cache set
    //fmt.Println("ReadLastestDiamond ", diamond)
    cs.lastestDiamond = &diamond <=== Write
    return &diamond, nil

    }

=-=-=-=-=-

  • ChainState Data Race # 2:
    WARNING: DATA RACE
    Read at 0x00c4201b0398 by goroutine 53:
    miner/diamondminer.(*DiamondMiner).RunMining()
    miner/diamondminer/worker.go:33 +0xab
    miner/diamondminer.(*DiamondMiner).Start.func1()
    miner/diamondminer/miner.go:70 +0x195

    Previous write at 0x00c4201b0398 by goroutine 63:
    chain/chainstatev2.(*ChainState).ReadLastestDiamond()
    chain/chainstatev2/last_status.go:144 +0x30f
    mint/blockchain.(*BlockChain).ValidateDiamondCreateAction()
    mint/blockchain/validatediamond.go:25 +0xd5
    miner/memtxpool.(*MemTxPool).checkDiamondCreate()
    miner/memtxpool/check.go:50 +0x78c
    miner/memtxpool.(*MemTxPool).AddTx()
    miner/memtxpool/add.go:94 +0x51c
    node/handler.GetTransactionSubmit()
    node/handler/newtxblock.go:94 +0x1c3
    node/backend.(*Backend).OnMsgData()
    node/backend/message.go:67 +0x28d
    node/p2pv2.(*P2P).handleConnMsg()
    node/p2pv2/tcp_msg_handler.go:39 +0x8f5

    Read:
    [miner/diamondminer/worker.go:33]
    func (d *DiamondMiner) RunMining(prevDiamond *stores.DiamondSmelt, diamondCreateActionCh chan *actions.Action_4_DiamondCreate) {
    d.changeLock.Lock()
    defer d.changeLock.Unlock()

    // stop prev all
    d.StopAll()

    fmt.Printf("do diamond mining... number: %d, supervene: %d, start worker:", prevDiamond.Number+1, d.Config.Supervene) <=== Read

    d.stopMarksLocker.Lock()
    var stopMark byte = 0
    d.stopMarks[&stopMark] = &stopMark
    defer d.stopMarksLocker.Unlock()

    // do mining
    go func(supervene int, stopMark *byte, prevDiamond *stores.DiamondSmelt, diamondCreateActionCh chan *actions.Action_4_DiamondCreate) {

      var current_i uint32 = 0
      var current_lock = sync.Mutex{}
    
      for i := 0; i < supervene; i++ {
      	go func(i int) {
      	NEXTMINING:
      		var my_i uint32 = 0
      		current_lock.Lock()
      		current_i++
      		my_i = current_i
      		current_lock.Unlock()
      		// call mining
      		tarnumber := int(prevDiamond.Number) + 1
      		retExtMsg := bytes.Repeat([]byte{0}, 32) // 随机字段值,让同一个地址配置也可以挖不同的的钻石
      		mnstart, mnend := my_i, my_i+1
      		if uint32(tarnumber) > actions.DiamondCreateCustomMessageAboveNumber {
      			mnstart, mnend = 0, 4294967290
      			rand.Read(retExtMsg)
      		}
      		fmt.Printf(" #%d", my_i)
      		retNonce, diamondFullStr := x16rs.MinerHacashDiamond(mnstart, mnend, tarnumber, stopMark, prevDiamond.ContainBlockHash, d.Config.Rewards, retExtMsg)
      		retNonceNum := binary.BigEndian.Uint64(retNonce)
      		if retNonceNum > 0 {
      			fmt.Printf("\n❂❂❂❂❂❂ [Diamond Miner] Success find a diamond: <%s>, number: %d, nonce: %d, extmsg: %s.\n\n",
      				diamondFullStr, tarnumber, retNonceNum, hex.EncodeToString(retExtMsg))
      			// success
      			diamondCreateActionCh <- parsediamondCreateAction(diamondFullStr, prevDiamond, retNonce, d.Config.Rewards, retExtMsg)
      			// set all stop
      			if !d.Config.Continued {
      				// 非连续挖矿
      				*stopMark = 1
      				return
      			}
      			// 连续不停的挖矿
      		}
    
      		if *stopMark == 1 {
      			return // set stop
      		}
      		// LOOP NEXT
      		goto NEXTMINING
      	}(i)
      }
    

    }(d.Config.Supervene, &stopMark, prevDiamond, diamondCreateActionCh)

    }

    Write:
    [chain/chainstatev2/last_status.go:144]
    func (cs *ChainState) ReadLastestDiamond() (*stores.DiamondSmelt, error) {
    //fmt.Println("ReadLastestDiamond >>>>>>>")
    cs.chainStateMutex.RLock()
    if cs.lastestDiamond != nil {
    defer cs.chainStateMutex.RUnlock()
    return cs.lastestDiamond, nil
    }
    if cs.base != nil {
    defer cs.chainStateMutex.RUnlock()
    return cs.base.ReadLastestDiamond()
    }
    cs.chainStateMutex.RUnlock()
    // read from status db
    //fmt.Println("ReadLastestDiamond >>>>>>> read from status db")
    vdatas, e3 := cs.laststatusDB.Get([]byte(LastestStatusKeyName_lastest_diamond))
    if e3 != nil {
    return nil, e3
    }
    // check
    if vdatas == nil {
    //fmt.Println("ReadLastestDiamond return nil, nil // first one")
    return nil, nil // first one
    }
    if len(vdatas) == 0 {
    return nil, fmt.Errorf("lastest_diamond store file error.")
    }
    var diamond stores.DiamondSmelt <=== Write
    _, err := diamond.Parse(vdatas, 0)
    if err != nil {
    return nil, err
    }
    // cache set
    //fmt.Println("ReadLastestDiamond ", diamond)
    cs.lastestDiamond = &diamond
    return &diamond, nil

    }

=-=-=-=-=-=-=-=-=-=-=-=-=-

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.