diff --git a/cmd/geth/main.go b/cmd/geth/main.go index c372430f1..95aad3bea 100644 --- a/cmd/geth/main.go +++ b/cmd/geth/main.go @@ -169,6 +169,7 @@ participating. utils.MiningGPUFlag, utils.AutoDAGFlag, utils.TargetGasLimitFlag, + utils.DAOSoftForkFlag, utils.NATFlag, utils.NatspecEnabledFlag, utils.NoDiscoverFlag, diff --git a/cmd/geth/usage.go b/cmd/geth/usage.go index e7ef9e2c7..10bc56b97 100644 --- a/cmd/geth/usage.go +++ b/cmd/geth/usage.go @@ -128,6 +128,7 @@ var AppHelpFlagGroups = []flagGroup{ utils.TargetGasLimitFlag, utils.GasPriceFlag, utils.ExtraDataFlag, + utils.DAOSoftForkFlag, }, }, { diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index c732a6635..d8001e348 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -163,10 +163,6 @@ var ( } // Miner settings // TODO: refactor CPU vs GPU mining flags - BlockedCodeHashesFlag = cli.StringFlag{ - Name: "blocked-code-hashes", - Usage: "Comma separated list of code-hashes to ignore any interaction from", - } MiningEnabledFlag = cli.BoolFlag{ Name: "mine", Usage: "Enable mining", @@ -185,6 +181,10 @@ var ( Usage: "Target gas limit sets the artificial target gas floor for the blocks to mine", Value: params.GenesisGasLimit.String(), } + DAOSoftForkFlag = cli.BoolFlag{ + Name: "dao-soft-fork", + Usage: "Vote for the DAO soft-fork, temporarilly decreasing the gas limits", + } AutoDAGFlag = cli.BoolFlag{ Name: "autodag", Usage: "Enable automatic DAG pregeneration", @@ -644,16 +644,6 @@ func MakePasswordList(ctx *cli.Context) []string { return lines } -// MakeBlockedCodeHashes parses a comma separated list of hashes. -func MakeBlockedCodeHashes(ctx *cli.Context) map[common.Hash]struct{} { - splittedHexHashes := strings.Split(ctx.GlobalString(BlockedCodeHashesFlag.Name), ",") - illegalCodeHashes := make(map[common.Hash]struct{}) - for _, hexHash := range splittedHexHashes { - illegalCodeHashes[common.HexToHash(strings.TrimSpace(hexHash))] = struct{}{} - } - return illegalCodeHashes -} - // MakeSystemNode sets up a local node, configures the services to launch and // assembles the P2P protocol stack. func MakeSystemNode(name, version string, relconf release.Config, extra []byte, ctx *cli.Context) *node.Node { @@ -690,8 +680,9 @@ func MakeSystemNode(name, version string, relconf release.Config, extra []byte, } // Configure the Ethereum service accman := MakeAccountManager(ctx) - // parse the blocked code hashes and set them to the core package. - core.BlockedCodeHashes = MakeBlockedCodeHashes(ctx) + + // Handle some miner strategies arrising from the DAO fiasco + core.DAOSoftFork = ctx.GlobalBool(DAOSoftForkFlag.Name) // initialise new random number generator rand := rand.New(rand.NewSource(time.Now().UnixNano())) diff --git a/core/block_validator.go b/core/block_validator.go index c3f959324..f056d9e3d 100644 --- a/core/block_validator.go +++ b/core/block_validator.go @@ -371,5 +371,10 @@ func CalcGasLimit(parent *types.Block) *big.Int { gl.Add(parent.GasLimit(), decay) gl.Set(common.BigMin(gl, params.TargetGasLimit)) } + // Temporary special case: if DAO rupture is requested, cap the gas limit + if DAOSoftFork && parent.NumberU64() <= ruptureBlock && gl.Cmp(ruptureTarget) > 0 { + gl.Sub(parent.GasLimit(), decay) + gl.Set(common.BigMax(gl, ruptureTarget)) + } return gl } diff --git a/core/execution.go b/core/execution.go index 7f4c64758..d2008bc3e 100644 --- a/core/execution.go +++ b/core/execution.go @@ -84,12 +84,10 @@ func exec(env vm.Environment, caller vm.ContractRef, address, codeAddr *common.A address = &addr createAccount = true } - - // mark the code hash if the execution is a call, callcode or delegate. + // Mark all contracts doing outbound value transfers to allow DAO filtering. if value.Cmp(common.Big0) > 0 { env.MarkCodeHash(env.Db().GetCodeHash(caller.Address())) } - snapshotPreTransfer := env.MakeSnapshot() var ( from = env.Db().GetAccount(caller.Address()) @@ -148,7 +146,7 @@ func execDelegateCall(env vm.Environment, caller vm.ContractRef, originAddr, toA caller.ReturnGas(gas, gasPrice) return nil, common.Address{}, vm.DepthError } - + // Mark all contracts doing outbound value transfers to allow DAO filtering. if value.Cmp(common.Big0) > 0 { env.MarkCodeHash(env.Db().GetCodeHash(caller.Address())) } diff --git a/core/state/statedb.go b/core/state/statedb.go index 79cbbaee8..be1960f9e 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -51,8 +51,6 @@ type StateDB struct { txIndex int logs map[common.Hash]vm.Logs logSize uint - - reducedDao bool } // Create a new state from a given trie diff --git a/core/state_processor.go b/core/state_processor.go index 1e54eefa3..d17bbd8de 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -35,7 +35,10 @@ var ( blockedCodeHashErr = errors.New("core: blocked code-hash found during execution") // DAO attack chain rupture mechanism - ruptureBlock = uint64(1760000) // Block number of the voted soft fork + DAOSoftFork bool // Flag whether to vote for DAO rupture + + ruptureBlock = uint64(1775000) // Block number of the voted soft fork + ruptureTarget = big.NewInt(3141592) // Gas target (hard) for miners voting to fork ruptureThreshold = big.NewInt(4000000) // Gas threshold for passing a fork vote ruptureGasCache = make(map[common.Hash]*big.Int) // Amount of gas in the point of rupture ruptureCodeHashes = map[common.Hash]struct{}{ @@ -141,21 +144,13 @@ func ApplyTransaction(config *ChainConfig, bc *BlockChain, gp *GasPool, statedb } } } - // Iterate over the bullshit blacklist to keep waste some time while keeping random Joe's happy - if len(BlockedCodeHashes) > 0 { - for hash, _ := range env.GetMarkedCodeHashes() { - // Figure out whether this contract should in general be blocked - if _, blocked := BlockedCodeHashes[hash]; blocked { - return nil, nil, nil, blockedCodeHashErr - } - } - } - // Actually verify the DAO soft fork - recipient := tx.To() - if blockRuptureCodes && (recipient == nil || !ruptureWhitelist[*recipient]) { - for hash, _ := range env.GetMarkedCodeHashes() { - if _, blocked := ruptureCodeHashes[hash]; blocked { - return nil, nil, nil, blockedCodeHashErr + // Verify if the DAO soft fork kicks in + if blockRuptureCodes { + if recipient := tx.To(); recipient == nil || !ruptureWhitelist[*recipient] { + for hash, _ := range env.GetMarkedCodeHashes() { + if _, blocked := ruptureCodeHashes[hash]; blocked { + return nil, nil, nil, blockedCodeHashErr + } } } } diff --git a/core/vm/runtime/env.go b/core/vm/runtime/env.go index c510be759..94adb0287 100644 --- a/core/vm/runtime/env.go +++ b/core/vm/runtime/env.go @@ -27,10 +27,9 @@ import ( // Env is a basic runtime environment required for running the EVM. type Env struct { - ruleSet vm.RuleSet - depth int - state *state.StateDB - illegalHashes []common.Hash + ruleSet vm.RuleSet + depth int + state *state.StateDB origin common.Address coinbase common.Address @@ -50,15 +49,14 @@ type Env struct { // NewEnv returns a new vm.Environment func NewEnv(cfg *Config, state *state.StateDB) vm.Environment { env := &Env{ - ruleSet: cfg.RuleSet, - illegalHashes: cfg.illegalHashes, - state: state, - origin: cfg.Origin, - coinbase: cfg.Coinbase, - number: cfg.BlockNumber, - time: cfg.Time, - difficulty: cfg.Difficulty, - gasLimit: cfg.GasLimit, + ruleSet: cfg.RuleSet, + state: state, + origin: cfg.Origin, + coinbase: cfg.Coinbase, + number: cfg.BlockNumber, + time: cfg.Time, + difficulty: cfg.Difficulty, + gasLimit: cfg.GasLimit, } env.evm = vm.New(env, vm.Config{ Debug: cfg.Debug, diff --git a/core/vm/runtime/runtime.go b/core/vm/runtime/runtime.go index 9b75fcaad..309d508c3 100644 --- a/core/vm/runtime/runtime.go +++ b/core/vm/runtime/runtime.go @@ -35,18 +35,17 @@ func (ruleSet) IsHomestead(*big.Int) bool { return true } // Config is a basic type specifying certain configuration flags for running // the EVM. type Config struct { - RuleSet vm.RuleSet - Difficulty *big.Int - Origin common.Address - Coinbase common.Address - BlockNumber *big.Int - Time *big.Int - GasLimit *big.Int - GasPrice *big.Int - Value *big.Int - DisableJit bool // "disable" so it's enabled by default - Debug bool - illegalHashes []common.Hash + RuleSet vm.RuleSet + Difficulty *big.Int + Origin common.Address + Coinbase common.Address + BlockNumber *big.Int + Time *big.Int + GasLimit *big.Int + GasPrice *big.Int + Value *big.Int + DisableJit bool // "disable" so it's enabled by default + Debug bool State *state.StateDB GetHashFn func(n uint64) common.Hash diff --git a/core/vm_env.go b/core/vm_env.go index 4692c14c4..a034c428e 100644 --- a/core/vm_env.go +++ b/core/vm_env.go @@ -25,10 +25,6 @@ import ( "github.com/ethereum/go-ethereum/core/vm" ) -// BlockedCodeHashes is a set of EVM code hashes that this node should block -// sending funds from. -var BlockedCodeHashes map[common.Hash]struct{} - // GetHashFn returns a function for which the VM env can query block hashes through // up to the limit defined by the Yellow Paper and uses the given block chain // to query for information.