|
| 1 | +// Copyright 2016 The go-ethereum Authors |
| 2 | +// This file is part of the go-ethereum library. |
| 3 | +// |
| 4 | +// The go-ethereum library is free software: you can redistribute it and/or modify |
| 5 | +// it under the terms of the GNU Lesser General Public License as published by |
| 6 | +// the Free Software Foundation, either version 3 of the License, or |
| 7 | +// (at your option) any later version. |
| 8 | +// |
| 9 | +// The go-ethereum library is distributed in the hope that it will be useful, |
| 10 | +// but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 11 | +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 12 | +// GNU Lesser General Public License for more details. |
| 13 | +// |
| 14 | +// You should have received a copy of the GNU Lesser General Public License |
| 15 | +// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. |
| 16 | + |
| 17 | +package core |
| 18 | + |
| 19 | +import ( |
| 20 | + "bytes" |
| 21 | + "math/big" |
| 22 | + |
| 23 | + "github.com/ethereum/go-ethereum/core/state" |
| 24 | + "github.com/ethereum/go-ethereum/core/types" |
| 25 | + "github.com/ethereum/go-ethereum/params" |
| 26 | +) |
| 27 | + |
| 28 | +// ValidateDAOHeaderExtraData validates the extra-data field of a block header to |
| 29 | +// ensure it conforms to DAO hard-fork rules. |
| 30 | +// |
| 31 | +// DAO hard-fork extension to the header validity: |
| 32 | +// a) if the node is no-fork, do not accept blocks in the [fork, fork+10) range |
| 33 | +// with the fork specific extra-data set |
| 34 | +// b) if the node is pro-fork, require blocks in the specific range to have the |
| 35 | +// unique extra-data set. |
| 36 | +func ValidateDAOHeaderExtraData(config *ChainConfig, header *types.Header) error { |
| 37 | + // Short circuit validation if the node doesn't care about the DAO fork |
| 38 | + if config.DAOForkBlock == nil { |
| 39 | + return nil |
| 40 | + } |
| 41 | + // Make sure the block is within the fork's modified extra-data range |
| 42 | + limit := new(big.Int).Add(config.DAOForkBlock, params.DAOForkExtraRange) |
| 43 | + if header.Number.Cmp(config.DAOForkBlock) < 0 || header.Number.Cmp(limit) >= 0 { |
| 44 | + return nil |
| 45 | + } |
| 46 | + // Depending whether we support or oppose the fork, validate the extra-data contents |
| 47 | + if config.DAOForkSupport { |
| 48 | + if bytes.Compare(header.Extra, params.DAOForkBlockExtra) != 0 { |
| 49 | + return ValidationError("DAO pro-fork bad block extra-data: 0x%x", header.Extra) |
| 50 | + } |
| 51 | + } else { |
| 52 | + if bytes.Compare(header.Extra, params.DAOForkBlockExtra) == 0 { |
| 53 | + return ValidationError("DAO no-fork bad block extra-data: 0x%x", header.Extra) |
| 54 | + } |
| 55 | + } |
| 56 | + // All ok, header has the same extra-data we expect |
| 57 | + return nil |
| 58 | +} |
| 59 | + |
| 60 | +// ApplyDAOHardFork modifies the state database according to the DAO hard-fork |
| 61 | +// rules, transferring all balances of a set of DAO accounts to a single refund |
| 62 | +// contract. |
| 63 | +func ApplyDAOHardFork(statedb *state.StateDB) { |
| 64 | + // Retrieve the contract to refund balances into |
| 65 | + refund := statedb.GetOrNewStateObject(params.DAORefundContract) |
| 66 | + |
| 67 | + // Move every DAO account and extra-balance account funds into the refund contract |
| 68 | + for _, addr := range params.DAODrainList { |
| 69 | + if account := statedb.GetStateObject(addr); account != nil { |
| 70 | + refund.AddBalance(account.Balance()) |
| 71 | + account.SetBalance(new(big.Int)) |
| 72 | + } |
| 73 | + } |
| 74 | +} |
0 commit comments