4
4
import com .google .common .collect .Streams ;
5
5
import com .google .protobuf .ByteString ;
6
6
import java .util .Arrays ;
7
- import java .util .HashSet ;
8
7
import java .util .List ;
9
- import java .util .Set ;
8
+ import java .util .Objects ;
10
9
import java .util .stream .Collectors ;
11
10
import java .util .stream .Stream ;
12
11
import lombok .AccessLevel ;
18
17
import org .tron .core .Wallet ;
19
18
import org .tron .core .capsule .BlockCapsule ;
20
19
import org .tron .core .config .Parameter .ForkBlockVersionConsts ;
20
+ import org .tron .core .config .Parameter .ForkBlockVersionEnum ;
21
21
import org .tron .core .db .Manager ;
22
22
23
23
@ Slf4j
24
24
@ NoArgsConstructor (access = AccessLevel .PRIVATE )
25
25
public class ForkController {
26
26
27
+ private static final byte VERSION_DOWNGRADE = (byte ) 0 ;
27
28
private static final byte VERSION_UPGRADE = (byte ) 1 ;
28
- private static final byte HARD_FORK_EFFECTIVE = (byte ) 2 ;
29
29
private static final byte [] check ;
30
- private static final byte [] check2 ;
30
+
31
31
static {
32
32
check = new byte [1024 ];
33
33
Arrays .fill (check , VERSION_UPGRADE );
34
- check2 = new byte [1024 ];
35
- Arrays .fill (check2 , HARD_FORK_EFFECTIVE );
36
34
}
37
35
38
36
@ Getter
39
37
private Manager manager ;
40
38
41
- private Set <Integer > passSet = new HashSet <>();
42
-
43
39
public void init (Manager manager ) {
44
40
this .manager = manager ;
45
- passSet .clear ();
46
41
}
47
42
48
- public synchronized boolean pass (int version ) {
49
- if (!checkEnergy (version )) {
50
- return false ;
51
- }
52
-
53
- if (passSet .contains (version )) {
54
- return true ;
55
- }
43
+ public boolean pass (ForkBlockVersionEnum forkBlockVersionEnum ) {
44
+ return pass (forkBlockVersionEnum .getValue ());
45
+ }
56
46
57
- byte [] stats = manager .getDynamicPropertiesStore ().statsByVersion (version );
58
- boolean pass ;
47
+ public synchronized boolean pass (int version ) {
59
48
if (version == ForkBlockVersionConsts .ENERGY_LIMIT ) {
60
- pass = check (stats );
61
- } else {
62
- pass = check2 (stats );
49
+ return checkForEnergyLimit ();
63
50
}
64
51
65
- if (pass ) {
66
- passSet .add (version );
67
- }
68
- return pass ;
52
+ byte [] stats = manager .getDynamicPropertiesStore ().statsByVersion (version );
53
+ return check (stats );
69
54
}
70
55
71
56
// when block.version = 5,
72
57
// it make block use new energy to handle transaction when block number >= 4727890L.
73
58
// version !=5, skip this.
74
- private boolean checkEnergy (int version ) {
75
- if (version != ForkBlockVersionConsts .ENERGY_LIMIT ) {
76
- return true ;
77
- }
78
-
59
+ private boolean checkForEnergyLimit () {
79
60
long blockNum = manager .getDynamicPropertiesStore ().getLatestBlockHeaderNumber ();
80
61
return blockNum >= 4727890L ;
81
62
}
82
63
83
64
private boolean check (byte [] stats ) {
84
- return check (check , stats );
85
- }
86
-
87
- private boolean check2 (byte [] stats ) {
88
- return check (check2 , stats );
89
- }
90
-
91
- private boolean check (byte [] check , byte [] stats ) {
92
65
if (stats == null || stats .length == 0 ) {
93
66
return false ;
94
67
}
@@ -102,6 +75,19 @@ private boolean check(byte[] check, byte[] stats) {
102
75
return true ;
103
76
}
104
77
78
+ private void downgrade (int version , int slot ) {
79
+ for (ForkBlockVersionEnum versionEnum : ForkBlockVersionEnum .values ()) {
80
+ int versionValue = versionEnum .getValue ();
81
+ if (versionValue > version ) {
82
+ byte [] stats = manager .getDynamicPropertiesStore ().statsByVersion (versionValue );
83
+ if (!check (stats ) && Objects .nonNull (stats )) {
84
+ stats [slot ] = VERSION_DOWNGRADE ;
85
+ manager .getDynamicPropertiesStore ().statsByVersion (versionValue , stats );
86
+ }
87
+ }
88
+ }
89
+ }
90
+
105
91
public synchronized void update (BlockCapsule blockCapsule ) {
106
92
List <ByteString > witnesses = manager .getWitnessController ().getActiveWitnesses ();
107
93
ByteString witness = blockCapsule .getWitnessAddress ();
@@ -111,16 +97,18 @@ public synchronized void update(BlockCapsule blockCapsule) {
111
97
}
112
98
113
99
int version = blockCapsule .getInstance ().getBlockHeader ().getRawData ().getVersion ();
114
- if (version < ForkBlockVersionConsts .ENERGY_LIMIT || passSet . contains ( version ) ) {
100
+ if (version < ForkBlockVersionConsts .ENERGY_LIMIT ) {
115
101
return ;
116
102
}
117
103
104
+ downgrade (version , slot );
105
+
118
106
byte [] stats = manager .getDynamicPropertiesStore ().statsByVersion (version );
119
- if (check (stats ) || check2 ( stats ) ) {
107
+ if (check (stats )) {
120
108
return ;
121
109
}
122
110
123
- if (stats == null ) {
111
+ if (Objects . isNull ( stats ) || stats . length != witnesses . size () ) {
124
112
stats = new byte [witnesses .size ()];
125
113
}
126
114
@@ -138,38 +126,14 @@ public synchronized void update(BlockCapsule blockCapsule) {
138
126
version );
139
127
}
140
128
141
- public synchronized void updateWhenMaintenance (BlockCapsule blockCapsule ) {
142
- int version = blockCapsule .getInstance ().getBlockHeader ().getRawData ().getVersion ();
143
- if (version < ForkBlockVersionConsts .VERSION_3_2_2 || passSet .contains (version )) {
144
- return ;
145
- }
146
-
147
- byte [] stats = manager .getDynamicPropertiesStore ().statsByVersion (version );
148
- if (check2 (stats )) {
149
- return ;
150
- }
151
-
152
- if (check (stats )) {
153
- Arrays .fill (stats , HARD_FORK_EFFECTIVE );
154
- manager .getDynamicPropertiesStore ().statsByVersion (version , stats );
155
- logger .info ("*******hard fork is effective in the maintenance, version is {}" , version );
156
- }
157
- }
158
-
159
- public synchronized void reset (BlockCapsule blockCapsule ) {
160
- int version = blockCapsule .getInstance ().getBlockHeader ().getRawData ().getVersion ();
161
- if (version < ForkBlockVersionConsts .ENERGY_LIMIT || passSet .contains (version )) {
162
- return ;
163
- }
164
-
165
- byte [] stats = manager .getDynamicPropertiesStore ().statsByVersion (version );
166
- if (check (stats ) || check2 (stats )) {
167
- return ;
168
- }
169
-
170
- if (stats != null ) {
171
- Arrays .fill (stats , (byte ) 0 );
172
- manager .getDynamicPropertiesStore ().statsByVersion (version , stats );
129
+ public synchronized void reset () {
130
+ for (ForkBlockVersionEnum versionEnum : ForkBlockVersionEnum .values ()) {
131
+ int versionValue = versionEnum .getValue ();
132
+ byte [] stats = manager .getDynamicPropertiesStore ().statsByVersion (versionValue );
133
+ if (!check (stats ) && Objects .nonNull (stats )) {
134
+ Arrays .fill (stats , VERSION_DOWNGRADE );
135
+ manager .getDynamicPropertiesStore ().statsByVersion (versionValue , stats );
136
+ }
173
137
}
174
138
}
175
139
0 commit comments