1919import org .tron .core .capsule .BlockCapsule ;
2020import org .tron .core .config .Parameter .ForkBlockVersionConsts ;
2121import org .tron .core .config .Parameter .ForkBlockVersionEnum ;
22+ import org .tron .core .store .DynamicPropertiesStore ;
2223
2324@ Slf4j (topic = "utils" )
2425public class ForkController {
@@ -37,6 +38,12 @@ public class ForkController {
3738
3839 public void init (ChainBaseManager manager ) {
3940 this .manager = manager ;
41+ try {
42+ checkLocalVersion ();
43+ } catch (RuntimeException r ) {
44+ logger .warn ("Exception caught, detail:{}" , r .getMessage ());
45+ System .exit (1 );
46+ }
4047 }
4148
4249 public boolean pass (ForkBlockVersionEnum forkBlockVersionEnum ) {
@@ -87,7 +94,7 @@ private boolean passNew(int version) {
8794 }
8895 }
8996 return count >= Math
90- .ceil ((double ) versionEnum .getHardForkRate () * manager . getWitnesses (). size () / 100 );
97+ .ceil ((double ) versionEnum .getHardForkRate () * stats . length / 100 );
9198 }
9299
93100
@@ -116,9 +123,9 @@ private boolean check(byte[] stats) {
116123 private void downgrade (int version , int slot ) {
117124 for (ForkBlockVersionEnum versionEnum : ForkBlockVersionEnum .values ()) {
118125 int versionValue = versionEnum .getValue ();
119- if (versionValue > version ) {
126+ if (versionValue > version && ! pass ( versionValue ) ) {
120127 byte [] stats = manager .getDynamicPropertiesStore ().statsByVersion (versionValue );
121- if (! check ( stats ) && Objects .nonNull (stats )) {
128+ if (Objects .nonNull (stats )) {
122129 stats [slot ] = VERSION_DOWNGRADE ;
123130 manager .getDynamicPropertiesStore ().statsByVersion (versionValue , stats );
124131 }
@@ -129,15 +136,13 @@ private void downgrade(int version, int slot) {
129136 private void upgrade (int version , int slotSize ) {
130137 for (ForkBlockVersionEnum versionEnum : ForkBlockVersionEnum .values ()) {
131138 int versionValue = versionEnum .getValue ();
132- if (versionValue < version ) {
139+ if (versionValue < version && ! pass ( versionValue ) ) {
133140 byte [] stats = manager .getDynamicPropertiesStore ().statsByVersion (versionValue );
134- if (!check (stats )) {
135- if (stats == null || stats .length == 0 ) {
136- stats = new byte [slotSize ];
137- }
138- Arrays .fill (stats , VERSION_UPGRADE );
139- manager .getDynamicPropertiesStore ().statsByVersion (versionValue , stats );
141+ if (stats == null || stats .length == 0 ) {
142+ stats = new byte [slotSize ];
140143 }
144+ Arrays .fill (stats , VERSION_UPGRADE );
145+ manager .getDynamicPropertiesStore ().statsByVersion (versionValue , stats );
141146 }
142147 }
143148 }
@@ -155,15 +160,20 @@ public synchronized void update(BlockCapsule blockCapsule) {
155160 return ;
156161 }
157162
163+ if (manager .getDynamicPropertiesStore ().getLatestVersion () >= version ) {
164+ return ;
165+ }
166+
158167 downgrade (version , slot );
159168
160169 byte [] stats = manager .getDynamicPropertiesStore ().statsByVersion (version );
161170 if (Objects .isNull (stats ) || stats .length != witnesses .size ()) {
162171 stats = new byte [witnesses .size ()];
163172 }
164173
165- if (check ( stats )) {
174+ if (pass ( version )) {
166175 upgrade (version , stats .length );
176+ manager .getDynamicPropertiesStore ().saveLatestVersion (version );
167177 return ;
168178 }
169179
@@ -185,11 +195,12 @@ public synchronized void update(BlockCapsule blockCapsule) {
185195 }
186196
187197 public synchronized void reset () {
198+ int size = manager .getWitnessScheduleStore ().getActiveWitnesses ().size ();
188199 for (ForkBlockVersionEnum versionEnum : ForkBlockVersionEnum .values ()) {
189200 int versionValue = versionEnum .getValue ();
190201 byte [] stats = manager .getDynamicPropertiesStore ().statsByVersion (versionValue );
191202 if (Objects .nonNull (stats ) && !pass (versionValue )) {
192- Arrays . fill ( stats , VERSION_DOWNGRADE ) ;
203+ stats = new byte [ size ] ;
193204 manager .getDynamicPropertiesStore ().statsByVersion (versionValue , stats );
194205 }
195206 }
@@ -212,4 +223,34 @@ private ForkController getInstance() {
212223 return instance ;
213224 }
214225 }
226+
227+ public void checkLocalVersion () {
228+ DynamicPropertiesStore store = manager .getDynamicPropertiesStore ();
229+ int latestVersion = store .getLatestVersion ();
230+ if (latestVersion == 0 ) {
231+ for (ForkBlockVersionEnum version : ForkBlockVersionEnum .values ()) {
232+ int v = version .getValue ();
233+ if (pass (v ) && latestVersion < v ) {
234+ latestVersion = v ;
235+ }
236+ }
237+ store .saveLatestVersion (latestVersion );
238+ return ;
239+ }
240+
241+ if (!CommonParameter .getInstance ().isVersionCheckEnable ()) {
242+ return ;
243+ }
244+
245+ int systemVersion = 0 ;
246+ for (ForkBlockVersionEnum version : ForkBlockVersionEnum .values ()) {
247+ if (version .getValue () > systemVersion ) {
248+ systemVersion = version .getValue ();
249+ }
250+ }
251+ if (latestVersion > systemVersion ) {
252+ throw new RuntimeException ("Version check failed, latestVersion:"
253+ + latestVersion + ", systemVersion:" + systemVersion );
254+ }
255+ }
215256}
0 commit comments