44import com .google .common .collect .Streams ;
55import com .google .protobuf .ByteString ;
66import java .util .Arrays ;
7- import java .util .HashSet ;
87import java .util .List ;
9- import java .util .Set ;
8+ import java .util .Objects ;
109import java .util .stream .Collectors ;
1110import java .util .stream .Stream ;
1211import lombok .AccessLevel ;
1817import org .tron .core .Wallet ;
1918import org .tron .core .capsule .BlockCapsule ;
2019import org .tron .core .config .Parameter .ForkBlockVersionConsts ;
20+ import org .tron .core .config .Parameter .ForkBlockVersionEnum ;
2121import org .tron .core .db .Manager ;
2222
2323@ Slf4j
2424@ NoArgsConstructor (access = AccessLevel .PRIVATE )
2525public class ForkController {
2626
27+ private static final byte VERSION_DOWNGRADE = (byte ) 0 ;
2728 private static final byte VERSION_UPGRADE = (byte ) 1 ;
28- private static final byte HARD_FORK_EFFECTIVE = (byte ) 2 ;
2929 private static final byte [] check ;
30- private static final byte [] check2 ;
30+
3131 static {
3232 check = new byte [1024 ];
3333 Arrays .fill (check , VERSION_UPGRADE );
34- check2 = new byte [1024 ];
35- Arrays .fill (check2 , HARD_FORK_EFFECTIVE );
3634 }
3735
3836 @ Getter
3937 private Manager manager ;
4038
41- private Set <Integer > passSet = new HashSet <>();
42-
4339 public void init (Manager manager ) {
4440 this .manager = manager ;
45- passSet .clear ();
4641 }
4742
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+ }
5646
57- byte [] stats = manager .getDynamicPropertiesStore ().statsByVersion (version );
58- boolean pass ;
47+ public synchronized boolean pass (int version ) {
5948 if (version == ForkBlockVersionConsts .ENERGY_LIMIT ) {
60- pass = check (stats );
61- } else {
62- pass = check2 (stats );
49+ return checkForEnergyLimit ();
6350 }
6451
65- if (pass ) {
66- passSet .add (version );
67- }
68- return pass ;
52+ byte [] stats = manager .getDynamicPropertiesStore ().statsByVersion (version );
53+ return check (stats );
6954 }
7055
7156 // when block.version = 5,
7257 // it make block use new energy to handle transaction when block number >= 4727890L.
7358 // 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 () {
7960 long blockNum = manager .getDynamicPropertiesStore ().getLatestBlockHeaderNumber ();
8061 return blockNum >= 4727890L ;
8162 }
8263
8364 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 ) {
9265 if (stats == null || stats .length == 0 ) {
9366 return false ;
9467 }
@@ -102,6 +75,19 @@ private boolean check(byte[] check, byte[] stats) {
10275 return true ;
10376 }
10477
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+
10591 public synchronized void update (BlockCapsule blockCapsule ) {
10692 List <ByteString > witnesses = manager .getWitnessController ().getActiveWitnesses ();
10793 ByteString witness = blockCapsule .getWitnessAddress ();
@@ -111,16 +97,18 @@ public synchronized void update(BlockCapsule blockCapsule) {
11197 }
11298
11399 int version = blockCapsule .getInstance ().getBlockHeader ().getRawData ().getVersion ();
114- if (version < ForkBlockVersionConsts .ENERGY_LIMIT || passSet . contains ( version ) ) {
100+ if (version < ForkBlockVersionConsts .ENERGY_LIMIT ) {
115101 return ;
116102 }
117103
104+ downgrade (version , slot );
105+
118106 byte [] stats = manager .getDynamicPropertiesStore ().statsByVersion (version );
119- if (check (stats ) || check2 ( stats ) ) {
107+ if (check (stats )) {
120108 return ;
121109 }
122110
123- if (stats == null ) {
111+ if (Objects . isNull ( stats ) || stats . length != witnesses . size () ) {
124112 stats = new byte [witnesses .size ()];
125113 }
126114
@@ -138,38 +126,14 @@ public synchronized void update(BlockCapsule blockCapsule) {
138126 version );
139127 }
140128
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+ }
173137 }
174138 }
175139
0 commit comments