Skip to content
This repository was archived by the owner on Dec 5, 2024. It is now read-only.

Commit d14781c

Browse files
authored
Merge pull request #944 from ethereum/hotfix/trie-npe
Fix NPE in a Trie flush
2 parents a7cffbe + 5fdacf7 commit d14781c

File tree

3 files changed

+37
-0
lines changed

3 files changed

+37
-0
lines changed

ethereumj-core/src/main/java/org/ethereum/trie/TrieImpl.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ public Node(byte[] hashOrRlp) {
9393

9494
private Node(RLP.LList parsedRlp) {
9595
this.parsedRlp = parsedRlp;
96+
this.rlp = parsedRlp.getEncoded();
9697
}
9798

9899
private Node(Object[] children) {

ethereumj-core/src/main/java/org/ethereum/util/RLP.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -710,6 +710,14 @@ public LList(byte[] rlp) {
710710
this.rlp = rlp;
711711
}
712712

713+
public byte[] getEncoded() {
714+
byte encoded[][] = new byte[cnt][];
715+
for (int i = 0; i < cnt; i++) {
716+
encoded[i] = encodeElement(getBytes(i));
717+
}
718+
return encodeList(encoded);
719+
}
720+
713721
public void add(int off, int len, boolean isList) {
714722
offsets[cnt] = off;
715723
lens[cnt] = isList ? (-1 - len) : len;

ethereumj-core/src/test/java/org/ethereum/trie/TrieTest.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1078,6 +1078,34 @@ public void testBugFix() throws ParseException, IOException, URISyntaxException
10781078
Hex.decode("00000000000000000000000000000000000000000000002f0000000000000000"));
10791079
}
10801080

1081+
@Test
1082+
public void testBugFix2() throws ParseException, IOException, URISyntaxException {
1083+
1084+
Source<byte[], byte[]> src = new HashMapDB<>();
1085+
1086+
// Create trie: root -> BranchNode (..., NodeValue (less than 32 bytes), ...)
1087+
TrieImpl trie = new TrieImpl(src);
1088+
trie.put(Hex.decode("0000000000000000000000000000000000000000000000000000000000000011"), Hex.decode("11"));
1089+
trie.put(Hex.decode("0000000000000000000000000000000000000000000000000000000000000022"), Hex.decode("22"));
1090+
trie.flush();
1091+
1092+
// Reset trie to refresh the nodes
1093+
trie = new TrieImpl(src, trie.getRootHash());
1094+
1095+
// Update trie: root -> dirty BranchNode (..., NodeValue (less than 32 bytes), ..., dirty NodeValue, ...)
1096+
trie.put(Hex.decode("0000000000000000000000000000000000000000000000000000000000000033"), Hex.decode("33"));
1097+
1098+
// BUG:
1099+
// In that case NodeValue (encoded as plain RLP list) isn't dirty
1100+
// while both rlp and hash fields are null, Node has been initialized with parsedRLP only
1101+
// Therefore any subsequent call to BranchNode.encode() fails with NPE
1102+
1103+
// FIX:
1104+
// Supply Node initialization with raw rlp value
1105+
1106+
assertEquals("36e350d9a1d9c02d5bc4539a05e51890784ea5d2b675a0b26725dbbdadb4d6e2", Hex.toHexString(trie.getRootHash()));
1107+
}
1108+
10811109
@Ignore
10821110
@Test
10831111
public void perfTestGet() {

0 commit comments

Comments
 (0)