Skip to content

Commit 52b3327

Browse files
authored
feat(db): optimize old rewards withdrawal (#5406)
1 parent db9f3be commit 52b3327

File tree

24 files changed

+969
-175
lines changed

24 files changed

+969
-175
lines changed

actuator/src/main/java/org/tron/core/utils/ProposalUtil.java

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -728,6 +728,26 @@ public static void validator(DynamicPropertiesStore dynamicPropertiesStore,
728728
}
729729
break;
730730
}
731+
case ALLOW_OLD_REWARD_OPT: {
732+
if (!forkController.pass(ForkBlockVersionEnum.VERSION_4_7_4)) {
733+
throw new ContractValidateException(
734+
"Bad chain parameter id [ALLOW_OLD_REWARD_OPT]");
735+
}
736+
if (value != 1) {
737+
throw new ContractValidateException(
738+
"This value[ALLOW_OLD_REWARD_OPT] is only allowed to be 1");
739+
}
740+
if (!dynamicPropertiesStore.useNewRewardAlgorithm()) {
741+
throw new ContractValidateException(
742+
"[ALLOW_NEW_REWARD] proposal must be approved "
743+
+ "before [ALLOW_OLD_REWARD_OPT] can be proposed");
744+
}
745+
if (dynamicPropertiesStore.useNewRewardAlgorithmFromStart()) {
746+
throw new ContractValidateException(
747+
"no need old reward opt, ALLOW_NEW_REWARD from start cycle 1");
748+
}
749+
break;
750+
}
731751
default:
732752
break;
733753
}
@@ -803,7 +823,8 @@ public enum ProposalType { // current value, value range
803823
DYNAMIC_ENERGY_MAX_FACTOR(75), // 0, [0, 100_000]
804824
ALLOW_TVM_SHANGHAI(76), // 0, 1
805825
ALLOW_CANCEL_ALL_UNFREEZE_V2(77), // 0, 1
806-
MAX_DELEGATE_LOCK_PERIOD(78); // (86400, 10512000]
826+
MAX_DELEGATE_LOCK_PERIOD(78), // (86400, 10512000]
827+
ALLOW_OLD_REWARD_OPT(79); // 0, 1
807828

808829
private long code;
809830

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,77 @@
11
package org.tron.core.db.common.iterator;
22

3+
import com.google.common.collect.Iterators;
4+
import com.google.common.collect.UnmodifiableIterator;
5+
import com.google.common.primitives.Bytes;
36
import java.io.Closeable;
47
import java.util.Iterator;
58
import java.util.Map.Entry;
9+
import java.util.NoSuchElementException;
610

7-
public interface DBIterator extends Iterator<Entry<byte[], byte[]>>, Closeable {
11+
public interface DBIterator extends Iterator<Entry<byte[], byte[]>>, AutoCloseable, Closeable {
812

13+
void seek(byte[] key);
14+
15+
void seekToFirst();
16+
17+
void seekToLast();
18+
19+
default UnmodifiableIterator<Entry<byte[], byte[]>> prefixQueryAfterThat
20+
(byte[] key, byte[] afterThat) {
21+
this.seek(afterThat == null ? key : afterThat);
22+
return Iterators.filter(this, entry -> Bytes.indexOf(entry.getKey(), key) == 0);
23+
}
24+
25+
/**
26+
* An iterator is either positioned at a key/value pair, or
27+
* not valid. This method returns true iff the iterator is valid.
28+
*
29+
* REQUIRES: iterator not closed
30+
*
31+
* @throws IllegalStateException if the iterator is closed.
32+
* @return an iterator is either positioned at a key/value pair
33+
*/
34+
boolean valid();
35+
36+
/**
37+
* The underlying storage for
38+
* the returned slice is valid only until the next modification of
39+
* the iterator.
40+
*
41+
* REQUIRES: valid() && !closed
42+
*
43+
* @throws IllegalStateException if the iterator is closed.
44+
* @throws NoSuchElementException if the iterator is not valid.
45+
*
46+
* @return the key for the current entry
47+
*/
48+
byte[] getKey();
49+
50+
/**
51+
* The underlying storage for
52+
* the returned slice is valid only until the next modification of
53+
* the iterator.
54+
*
55+
* REQUIRES: valid() && !closed
56+
*
57+
* @throws IllegalStateException if the iterator is closed.
58+
* @throws NoSuchElementException if the iterator is not valid.
59+
*
60+
* @return the value for the current entry
61+
*/
62+
byte[] getValue();
63+
64+
/**
65+
* @throws IllegalStateException if the iterator is closed.
66+
*/
67+
void checkState();
68+
69+
/**
70+
* @throws NoSuchElementException if the iterator is not valid.
71+
*/
72+
default void checkValid() {
73+
if (!valid()) {
74+
throw new NoSuchElementException();
75+
}
76+
}
977
}

chainbase/src/main/java/org/tron/core/db/common/iterator/RockStoreIterator.java

Lines changed: 58 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import java.io.IOException;
44
import java.util.Map.Entry;
55
import java.util.NoSuchElementException;
6+
import java.util.concurrent.atomic.AtomicBoolean;
67
import lombok.extern.slf4j.Slf4j;
78
import org.rocksdb.RocksIterator;
89

@@ -13,20 +14,22 @@ public final class RockStoreIterator implements DBIterator {
1314
private final RocksIterator dbIterator;
1415
private boolean first = true;
1516

16-
private boolean valid = true;
17+
private final AtomicBoolean close = new AtomicBoolean(false);
1718

1819
public RockStoreIterator(RocksIterator dbIterator) {
1920
this.dbIterator = dbIterator;
2021
}
2122

2223
@Override
2324
public void close() throws IOException {
24-
dbIterator.close();
25+
if (close.compareAndSet(false, true)) {
26+
dbIterator.close();
27+
}
2528
}
2629

2730
@Override
2831
public boolean hasNext() {
29-
if (!valid) {
32+
if (close.get()) {
3033
return false;
3134
}
3235
boolean hasNext = false;
@@ -37,13 +40,12 @@ public boolean hasNext() {
3740
first = false;
3841
}
3942
if (!(hasNext = dbIterator.isValid())) { // false is last item
40-
dbIterator.close();
41-
valid = false;
43+
close();
4244
}
4345
} catch (Exception e) {
4446
logger.error(e.getMessage(), e);
4547
try {
46-
dbIterator.close();
48+
close();
4749
} catch (Exception e1) {
4850
logger.error(e.getMessage(), e);
4951
}
@@ -53,7 +55,7 @@ public boolean hasNext() {
5355

5456
@Override
5557
public Entry<byte[], byte[]> next() {
56-
if (!valid) {
58+
if (close.get()) {
5759
throw new NoSuchElementException();
5860
}
5961
byte[] key = dbIterator.key();
@@ -76,4 +78,52 @@ public byte[] setValue(byte[] value) {
7678
}
7779
};
7880
}
79-
}
81+
82+
@Override
83+
public void seek(byte[] key) {
84+
checkState();
85+
dbIterator.seek(key);
86+
this.first = false;
87+
}
88+
89+
@Override
90+
public void seekToFirst() {
91+
checkState();
92+
dbIterator.seekToFirst();
93+
this.first = false;
94+
}
95+
96+
@Override
97+
public void seekToLast() {
98+
checkState();
99+
dbIterator.seekToLast();
100+
this.first = false;
101+
}
102+
103+
@Override
104+
public boolean valid() {
105+
checkState();
106+
return dbIterator.isValid();
107+
}
108+
109+
@Override
110+
public byte[] getKey() {
111+
checkState();
112+
checkValid();
113+
return dbIterator.key();
114+
}
115+
116+
@Override
117+
public byte[] getValue() {
118+
checkState();
119+
checkValid();
120+
return dbIterator.value();
121+
}
122+
123+
@Override
124+
public void checkState() {
125+
if (close.get()) {
126+
throw new IllegalStateException("iterator has been closed");
127+
}
128+
}
129+
}

chainbase/src/main/java/org/tron/core/db/common/iterator/StoreIterator.java

Lines changed: 57 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import java.io.IOException;
44
import java.util.Map.Entry;
55
import java.util.NoSuchElementException;
6+
import java.util.concurrent.atomic.AtomicBoolean;
67
import lombok.extern.slf4j.Slf4j;
78
import org.iq80.leveldb.DBIterator;
89

@@ -13,20 +14,22 @@ public final class StoreIterator implements org.tron.core.db.common.iterator.DBI
1314
private final DBIterator dbIterator;
1415
private boolean first = true;
1516

16-
private boolean valid = true;
17+
private final AtomicBoolean close = new AtomicBoolean(false);
1718

1819
public StoreIterator(DBIterator dbIterator) {
1920
this.dbIterator = dbIterator;
2021
}
2122

2223
@Override
2324
public void close() throws IOException {
24-
dbIterator.close();
25+
if (close.compareAndSet(false, true)) {
26+
dbIterator.close();
27+
}
2528
}
2629

2730
@Override
2831
public boolean hasNext() {
29-
if (!valid) {
32+
if (close.get()) {
3033
return false;
3134
}
3235

@@ -39,8 +42,7 @@ public boolean hasNext() {
3942
}
4043

4144
if (!(hasNext = dbIterator.hasNext())) { // false is last item
42-
dbIterator.close();
43-
valid = false;
45+
close();
4446
}
4547
} catch (Exception e) {
4648
logger.error(e.getMessage(), e);
@@ -51,7 +53,7 @@ public boolean hasNext() {
5153

5254
@Override
5355
public Entry<byte[], byte[]> next() {
54-
if (!valid) {
56+
if (close.get()) {
5557
throw new NoSuchElementException();
5658
}
5759
return dbIterator.next();
@@ -61,4 +63,53 @@ public Entry<byte[], byte[]> next() {
6163
public void remove() {
6264
throw new UnsupportedOperationException();
6365
}
66+
67+
@Override
68+
public void seek(byte[] key) {
69+
checkState();
70+
dbIterator.seek(key);
71+
this.first = false;
72+
}
73+
74+
@Override
75+
public void seekToFirst() {
76+
checkState();
77+
dbIterator.seekToFirst();
78+
this.first = false;
79+
}
80+
81+
@Override
82+
public void seekToLast() {
83+
checkState();
84+
dbIterator.seekToLast();
85+
this.first = false;
86+
}
87+
88+
@Override
89+
public boolean valid() {
90+
checkState();
91+
return dbIterator.hasNext();
92+
}
93+
94+
@Override
95+
public byte[] getKey() {
96+
checkState();
97+
checkValid();
98+
return dbIterator.peekNext().getKey();
99+
}
100+
101+
@Override
102+
public byte[] getValue() {
103+
checkState();
104+
checkValid();
105+
return dbIterator.peekNext().getValue();
106+
}
107+
108+
@Override
109+
public void checkState() {
110+
if (close.get()) {
111+
throw new IllegalStateException("iterator has been closed");
112+
}
113+
}
64114
}
115+

0 commit comments

Comments
 (0)