github.com/arieschain/arieschain@v0.0.0-20191023063405-37c074544356/consensus/misc/dao.go (about) 1 package misc 2 3 import ( 4 "bytes" 5 "errors" 6 "math/big" 7 8 "github.com/quickchainproject/quickchain/core/state" 9 "github.com/quickchainproject/quickchain/core/types" 10 "github.com/quickchainproject/quickchain/params" 11 ) 12 13 var ( 14 // ErrBadProDAOExtra is returned if a header doens't support the DAO fork on a 15 // pro-fork client. 16 ErrBadProDAOExtra = errors.New("bad DAO pro-fork extra-data") 17 18 // ErrBadNoDAOExtra is returned if a header does support the DAO fork on a no- 19 // fork client. 20 ErrBadNoDAOExtra = errors.New("bad DAO no-fork extra-data") 21 ) 22 23 // VerifyDAOHeaderExtraData validates the extra-data field of a block header to 24 // ensure it conforms to DAO hard-fork rules. 25 // 26 // DAO hard-fork extension to the header validity: 27 // a) if the node is no-fork, do not accept blocks in the [fork, fork+10) range 28 // with the fork specific extra-data set 29 // b) if the node is pro-fork, require blocks in the specific range to have the 30 // unique extra-data set. 31 func VerifyDAOHeaderExtraData(config *params.ChainConfig, header *types.Header) error { 32 // Short circuit validation if the node doesn't care about the DAO fork 33 if config.DAOForkBlock == nil { 34 return nil 35 } 36 // Make sure the block is within the fork's modified extra-data range 37 limit := new(big.Int).Add(config.DAOForkBlock, params.DAOForkExtraRange) 38 if header.Number.Cmp(config.DAOForkBlock) < 0 || header.Number.Cmp(limit) >= 0 { 39 return nil 40 } 41 // Depending on whether we support or oppose the fork, validate the extra-data contents 42 if config.DAOForkSupport { 43 if !bytes.Equal(header.Extra, params.DAOForkBlockExtra) { 44 return ErrBadProDAOExtra 45 } 46 } else { 47 if bytes.Equal(header.Extra, params.DAOForkBlockExtra) { 48 return ErrBadNoDAOExtra 49 } 50 } 51 // All ok, header has the same extra-data we expect 52 return nil 53 } 54 55 // ApplyDAOHardFork modifies the state database according to the DAO hard-fork 56 // rules, transferring all balances of a set of DAO accounts to a single refund 57 // contract. 58 func ApplyDAOHardFork(statedb *state.StateDB) { 59 // Retrieve the contract to refund balances into 60 if !statedb.Exist(params.DAORefundContract) { 61 statedb.CreateAccount(params.DAORefundContract) 62 } 63 64 // Move every DAO account and extra-balance account funds into the refund contract 65 for _, addr := range params.DAODrainList() { 66 statedb.AddBalance(params.DAORefundContract, statedb.GetBalance(addr)) 67 statedb.SetBalance(addr, new(big.Int)) 68 } 69 }