diff --git a/cmd/geth/main.go b/cmd/geth/main.go index 95aad3beae..c372430f1c 100644 --- a/cmd/geth/main.go +++ b/cmd/geth/main.go @@ -169,7 +169,6 @@ 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 10bc56b97c..e7ef9e2c7b 100644 --- a/cmd/geth/usage.go +++ b/cmd/geth/usage.go @@ -128,7 +128,6 @@ var AppHelpFlagGroups = []flagGroup{ utils.TargetGasLimitFlag, utils.GasPriceFlag, utils.ExtraDataFlag, - utils.DAOSoftForkFlag, }, }, { diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index d8001e3484..c732a6635e 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -163,6 +163,10 @@ 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", @@ -181,10 +185,6 @@ 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,6 +644,16 @@ 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 { @@ -680,9 +690,8 @@ func MakeSystemNode(name, version string, relconf release.Config, extra []byte, } // Configure the Ethereum service accman := MakeAccountManager(ctx) - - // Handle some miner strategies arrising from the DAO fiasco - core.DAOSoftFork = ctx.GlobalBool(DAOSoftForkFlag.Name) + // parse the blocked code hashes and set them to the core package. + core.BlockedCodeHashes = MakeBlockedCodeHashes(ctx) // 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 f056d9e3de..c3f959324a 100644 --- a/core/block_validator.go +++ b/core/block_validator.go @@ -371,10 +371,5 @@ 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 d2008bc3e9..7f4c647586 100644 --- a/core/execution.go +++ b/core/execution.go @@ -84,10 +84,12 @@ func exec(env vm.Environment, caller vm.ContractRef, address, codeAddr *common.A address = &addr createAccount = true } - // Mark all contracts doing outbound value transfers to allow DAO filtering. + + // mark the code hash if the execution is a call, callcode or delegate. if value.Cmp(common.Big0) > 0 { env.MarkCodeHash(env.Db().GetCodeHash(caller.Address())) } + snapshotPreTransfer := env.MakeSnapshot() var ( from = env.Db().GetAccount(caller.Address()) @@ -146,7 +148,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 be1960f9e9..79cbbaee8e 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -51,6 +51,8 @@ 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 d17bbd8de0..1e54eefa32 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -35,10 +35,7 @@ var ( blockedCodeHashErr = errors.New("core: blocked code-hash found during execution") // DAO attack chain rupture mechanism - 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 + ruptureBlock = uint64(1760000) // Block number of the voted soft 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{}{ @@ -144,13 +141,21 @@ func ApplyTransaction(config *ChainConfig, bc *BlockChain, gp *GasPool, statedb } } } - // 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 - } + // 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 } } } diff --git a/core/vm/runtime/env.go b/core/vm/runtime/env.go index 94adb0287f..c510be7592 100644 --- a/core/vm/runtime/env.go +++ b/core/vm/runtime/env.go @@ -27,9 +27,10 @@ import ( // Env is a basic runtime environment required for running the EVM. type Env struct { - ruleSet vm.RuleSet - depth int - state *state.StateDB + ruleSet vm.RuleSet + depth int + state *state.StateDB + illegalHashes []common.Hash origin common.Address coinbase common.Address @@ -49,14 +50,15 @@ type Env struct { // NewEnv returns a new vm.Environment func NewEnv(cfg *Config, state *state.StateDB) vm.Environment { env := &Env{ - ruleSet: cfg.RuleSet, - state: state, - origin: cfg.Origin, - coinbase: cfg.Coinbase, - number: cfg.BlockNumber, - time: cfg.Time, - difficulty: cfg.Difficulty, - gasLimit: cfg.GasLimit, + 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, } 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 309d508c3d..9b75fcaad0 100644 --- a/core/vm/runtime/runtime.go +++ b/core/vm/runtime/runtime.go @@ -35,17 +35,18 @@ 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 + 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 State *state.StateDB GetHashFn func(n uint64) common.Hash diff --git a/core/vm_env.go b/core/vm_env.go index a034c428ee..4692c14c4b 100644 --- a/core/vm_env.go +++ b/core/vm_env.go @@ -25,6 +25,10 @@ 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.