Skip to content

Commit 00e349b

Browse files
committed
fix getting last account address
1 parent 554b4dc commit 00e349b

File tree

5 files changed

+216
-63
lines changed

5 files changed

+216
-63
lines changed

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

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import java.io.Closeable;
77
import java.util.Iterator;
88
import java.util.Map.Entry;
9+
import java.util.NoSuchElementException;
910

1011
public interface DBIterator extends Iterator<Entry<byte[], byte[]>>, AutoCloseable, Closeable {
1112

@@ -20,4 +21,57 @@ public interface DBIterator extends Iterator<Entry<byte[], byte[]>>, AutoCloseab
2021
this.seek(afterThat == null ? key : afterThat);
2122
return Iterators.filter(this, entry -> Bytes.indexOf(entry.getKey(), key) == 0);
2223
}
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+
}
2377
}

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

Lines changed: 41 additions & 9 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,23 +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-
if (valid) {
25+
if (close.compareAndSet(false, true)) {
2526
dbIterator.close();
26-
valid = false;
2727
}
2828
}
2929

3030
@Override
3131
public boolean hasNext() {
32-
if (!valid) {
32+
if (close.get()) {
3333
return false;
3434
}
3535
boolean hasNext = false;
@@ -40,13 +40,12 @@ public boolean hasNext() {
4040
first = false;
4141
}
4242
if (!(hasNext = dbIterator.isValid())) { // false is last item
43-
dbIterator.close();
44-
valid = false;
43+
close();
4544
}
4645
} catch (Exception e) {
4746
logger.error(e.getMessage(), e);
4847
try {
49-
dbIterator.close();
48+
close();
5049
} catch (Exception e1) {
5150
logger.error(e.getMessage(), e);
5251
}
@@ -56,7 +55,7 @@ public boolean hasNext() {
5655

5756
@Override
5857
public Entry<byte[], byte[]> next() {
59-
if (!valid) {
58+
if (close.get()) {
6059
throw new NoSuchElementException();
6160
}
6261
byte[] key = dbIterator.key();
@@ -82,16 +81,49 @@ public byte[] setValue(byte[] value) {
8281

8382
@Override
8483
public void seek(byte[] key) {
84+
checkState();
8585
dbIterator.seek(key);
86+
this.first = false;
8687
}
8788

8889
@Override
8990
public void seekToFirst() {
91+
checkState();
9092
dbIterator.seekToFirst();
93+
this.first = false;
9194
}
9295

9396
@Override
9497
public void seekToLast() {
98+
checkState();
9599
dbIterator.seekToLast();
100+
this.first = false;
96101
}
97-
}
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: 40 additions & 7 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,23 +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-
if (valid) {
25+
if (close.compareAndSet(false, true)) {
2526
dbIterator.close();
26-
valid = false;
2727
}
2828
}
2929

3030
@Override
3131
public boolean hasNext() {
32-
if (!valid) {
32+
if (close.get()) {
3333
return false;
3434
}
3535

@@ -42,8 +42,7 @@ public boolean hasNext() {
4242
}
4343

4444
if (!(hasNext = dbIterator.hasNext())) { // false is last item
45-
dbIterator.close();
46-
valid = false;
45+
close();
4746
}
4847
} catch (Exception e) {
4948
logger.error(e.getMessage(), e);
@@ -54,7 +53,7 @@ public boolean hasNext() {
5453

5554
@Override
5655
public Entry<byte[], byte[]> next() {
57-
if (!valid) {
56+
if (close.get()) {
5857
throw new NoSuchElementException();
5958
}
6059
return dbIterator.next();
@@ -67,16 +66,50 @@ public void remove() {
6766

6867
@Override
6968
public void seek(byte[] key) {
69+
checkState();
7070
dbIterator.seek(key);
71+
this.first = false;
7172
}
7273

7374
@Override
7475
public void seekToFirst() {
76+
checkState();
7577
dbIterator.seekToFirst();
78+
this.first = false;
7679
}
7780

7881
@Override
7982
public void seekToLast() {
83+
checkState();
8084
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+
}
81113
}
82114
}
115+

chainbase/src/main/java/org/tron/core/service/RewardCalService.java

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -75,13 +75,7 @@ private void destroy() {
7575
}
7676

7777
public void calReward() throws IOException {
78-
try (DBIterator iterator = rewardCacheStore.iterator()) {
79-
iterator.seekToLast();
80-
if (iterator.hasNext()) {
81-
byte[] key = iterator.next().getKey();
82-
System.arraycopy(key, 0, lastAccount, 0, ADDRESS_SIZE);
83-
}
84-
}
78+
initLastAccount();
8579
es.submit(this::startRewardCal);
8680
}
8781

@@ -93,14 +87,18 @@ public void calRewardForTest() throws IOException {
9387
return;
9488
}
9589
accountIterator = (DBIterator) accountStore.getDb().iterator();
90+
initLastAccount();
91+
startRewardCal();
92+
}
93+
94+
private void initLastAccount() throws IOException {
9695
try (DBIterator iterator = rewardCacheStore.iterator()) {
9796
iterator.seekToLast();
98-
if (iterator.hasNext()) {
99-
byte[] key = iterator.next().getKey();
97+
if (iterator.valid()) {
98+
byte[] key = iterator.getKey();
10099
System.arraycopy(key, 0, lastAccount, 0, ADDRESS_SIZE);
101100
}
102101
}
103-
startRewardCal();
104102
}
105103

106104

0 commit comments

Comments
 (0)