75 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
		
		
			
		
	
	
			75 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| 
								 | 
							
								// Copyright 2016 The go-ethereum Authors
							 | 
						||
| 
								 | 
							
								// This file is part of the go-ethereum library.
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								// The go-ethereum library is free software: you can redistribute it and/or modify
							 | 
						||
| 
								 | 
							
								// it under the terms of the GNU Lesser General Public License as published by
							 | 
						||
| 
								 | 
							
								// the Free Software Foundation, either version 3 of the License, or
							 | 
						||
| 
								 | 
							
								// (at your option) any later version.
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								// The go-ethereum library is distributed in the hope that it will be useful,
							 | 
						||
| 
								 | 
							
								// but WITHOUT ANY WARRANTY; without even the implied warranty of
							 | 
						||
| 
								 | 
							
								// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
							 | 
						||
| 
								 | 
							
								// GNU Lesser General Public License for more details.
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								// You should have received a copy of the GNU Lesser General Public License
							 | 
						||
| 
								 | 
							
								// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								package core
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								import (
							 | 
						||
| 
								 | 
							
									"bytes"
							 | 
						||
| 
								 | 
							
									"math/big"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									"github.com/ethereum/go-ethereum/core/state"
							 | 
						||
| 
								 | 
							
									"github.com/ethereum/go-ethereum/core/types"
							 | 
						||
| 
								 | 
							
									"github.com/ethereum/go-ethereum/params"
							 | 
						||
| 
								 | 
							
								)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// ValidateDAOHeaderExtraData validates the extra-data field of a block header to
							 | 
						||
| 
								 | 
							
								// ensure it conforms to DAO hard-fork rules.
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								// DAO hard-fork extension to the header validity:
							 | 
						||
| 
								 | 
							
								//   a) if the node is no-fork, do not accept blocks in the [fork, fork+10) range
							 | 
						||
| 
								 | 
							
								//      with the fork specific extra-data set
							 | 
						||
| 
								 | 
							
								//   b) if the node is pro-fork, require blocks in the specific range to have the
							 | 
						||
| 
								 | 
							
								//      unique extra-data set.
							 | 
						||
| 
								 | 
							
								func ValidateDAOHeaderExtraData(config *ChainConfig, header *types.Header) error {
							 | 
						||
| 
								 | 
							
									// Short circuit validation if the node doesn't care about the DAO fork
							 | 
						||
| 
								 | 
							
									if config.DAOForkBlock == nil {
							 | 
						||
| 
								 | 
							
										return nil
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									// Make sure the block is within the fork's modified extra-data range
							 | 
						||
| 
								 | 
							
									limit := new(big.Int).Add(config.DAOForkBlock, params.DAOForkExtraRange)
							 | 
						||
| 
								 | 
							
									if header.Number.Cmp(config.DAOForkBlock) < 0 || header.Number.Cmp(limit) >= 0 {
							 | 
						||
| 
								 | 
							
										return nil
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									// Depending whether we support or oppose the fork, validate the extra-data contents
							 | 
						||
| 
								 | 
							
									if config.DAOForkSupport {
							 | 
						||
| 
								 | 
							
										if bytes.Compare(header.Extra, params.DAOForkBlockExtra) != 0 {
							 | 
						||
| 
								 | 
							
											return ValidationError("DAO pro-fork bad block extra-data: 0x%x", header.Extra)
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									} else {
							 | 
						||
| 
								 | 
							
										if bytes.Compare(header.Extra, params.DAOForkBlockExtra) == 0 {
							 | 
						||
| 
								 | 
							
											return ValidationError("DAO no-fork bad block extra-data: 0x%x", header.Extra)
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									// All ok, header has the same extra-data we expect
							 | 
						||
| 
								 | 
							
									return nil
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// ApplyDAOHardFork modifies the state database according to the DAO hard-fork
							 | 
						||
| 
								 | 
							
								// rules, transferring all balances of a set of DAO accounts to a single refund
							 | 
						||
| 
								 | 
							
								// contract.
							 | 
						||
| 
								 | 
							
								func ApplyDAOHardFork(statedb *state.StateDB) {
							 | 
						||
| 
								 | 
							
									// Retrieve the contract to refund balances into
							 | 
						||
| 
								 | 
							
									refund := statedb.GetOrNewStateObject(params.DAORefundContract)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									// Move every DAO account and extra-balance account funds into the refund contract
							 | 
						||
| 
								 | 
							
									for _, addr := range params.DAODrainList {
							 | 
						||
| 
								 | 
							
										if account := statedb.GetStateObject(addr); account != nil {
							 | 
						||
| 
								 | 
							
											refund.AddBalance(account.Balance())
							 | 
						||
| 
								 | 
							
											account.SetBalance(new(big.Int))
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 |