@@ -32,13 +32,20 @@ import (
32
32
var (
33
33
big8 = big .NewInt (8 )
34
34
big32 = big .NewInt (32 )
35
- illegalCodeHashErr = errors .New ("core: Illegal code-hash found during execution" )
36
- // XXX remove me
37
- daoHash = common .HexToHash ("7278d050619a624f84f51987149ddb439cdaadfba5966f7cfaea7ad44340a4ba" )
38
- whitelist = map [common.Address ]bool {
35
+ blockedCodeHashErr = errors .New ("core: blocked code-hash found during execution" )
36
+
37
+ // DAO attack chain rupture mechanism
38
+ ruptureBlock = uint64 (1760000 ) // Block number of the voted soft fork
39
+ ruptureThreshold = big .NewInt (4000000 ) // Gas threshold for passing a fork vote
40
+ ruptureGasCache = make (map [common.Hash ]* big.Int ) // Amount of gas in the point of rupture
41
+ ruptureCodeHashes = map [common.Hash ]struct {}{
42
+ common .HexToHash ("6a5d24750f78441e56fec050dc52fe8e911976485b7472faac7464a176a67caa" ): struct {}{},
43
+ }
44
+ ruptureWhitelist = map [common.Address ]bool {
39
45
common .HexToAddress ("Da4a4626d3E16e094De3225A751aAb7128e96526" ): true , // multisig
40
46
common .HexToAddress ("2ba9D006C1D72E67A70b5526Fc6b4b0C0fd6D334" ): true , // attack contract
41
47
}
48
+ ruptureCacheLimit = 30000 // 1 epoch, 0.5 per possible fork
42
49
)
43
50
44
51
// StateProcessor is a basic Processor, which takes care of transitioning
@@ -101,14 +108,58 @@ func ApplyTransaction(config *ChainConfig, bc *BlockChain, gp *GasPool, statedb
101
108
return nil , nil , nil , err
102
109
}
103
110
104
- for _ , codeHash := range env .CodeHashes {
105
- _ , illegalHash := IllegalCodeHashes [codeHash ]
106
- to := tx .To ()
107
- if illegalHash && to != nil && ! whitelist [* to ] {
108
- return nil , nil , nil , illegalCodeHashErr
111
+ // Check whether the DAO needs to be blocked or not
112
+ if bc != nil { // Test chain maker uses nil to construct the potential chain
113
+ blockRuptureCodes := false
114
+
115
+ if number := header .Number .Uint64 (); number >= ruptureBlock {
116
+ // We're past the rupture point, find the vote result on this chain and apply it
117
+ ancestry := []common.Hash {header .Hash (), header .ParentHash }
118
+ for _ , ok := ruptureGasCache [ancestry [len (ancestry )- 1 ]]; ! ok && number >= ruptureBlock + uint64 (len (ancestry )); {
119
+ ancestry = append (ancestry , bc .GetHeader (ancestry [len (ancestry )- 1 ]).ParentHash )
120
+ }
121
+ decider := ancestry [len (ancestry )- 1 ]
122
+
123
+ vote , ok := ruptureGasCache [decider ]
124
+ if ! ok {
125
+ // We've reached the rupture point, retrieve the vote
126
+ vote = bc .GetHeader (decider ).GasLimit
127
+ ruptureGasCache [decider ] = vote
128
+ }
129
+ // Cache the vote result for all ancestors and check the DAO
130
+ for _ , hash := range ancestry {
131
+ ruptureGasCache [hash ] = vote
132
+ }
133
+ if ruptureGasCache [ancestry [0 ]].Cmp (ruptureThreshold ) <= 0 {
134
+ blockRuptureCodes = true
135
+ }
136
+ // Make sure we don't OOM long run due to too many votes caching up
137
+ for len (ruptureGasCache ) > ruptureCacheLimit {
138
+ for hash , _ := range ruptureGasCache {
139
+ delete (ruptureGasCache , hash )
140
+ break
141
+ }
142
+ }
143
+ }
144
+ // Iterate over the bullshit blacklist to keep waste some time while keeping random Joe's happy
145
+ if len (BlockedCodeHashes ) > 0 {
146
+ for hash , _ := range env .GetMarkedCodeHashes () {
147
+ // Figure out whether this contract should in general be blocked
148
+ if _ , blocked := BlockedCodeHashes [hash ]; blocked {
149
+ return nil , nil , nil , blockedCodeHashErr
150
+ }
151
+ }
152
+ }
153
+ // Actually verify the DAO soft fork
154
+ recipient := tx .To ()
155
+ if blockRuptureCodes && (recipient == nil || ! ruptureWhitelist [* recipient ]) {
156
+ for hash , _ := range env .GetMarkedCodeHashes () {
157
+ if _ , blocked := ruptureCodeHashes [hash ]; blocked {
158
+ return nil , nil , nil , blockedCodeHashErr
159
+ }
160
+ }
109
161
}
110
162
}
111
-
112
163
// Update the state with pending changes
113
164
usedGas .Add (usedGas , gas )
114
165
receipt := types .NewReceipt (statedb .IntermediateRoot ().Bytes (), usedGas )
0 commit comments