Skip to content

Commit

Permalink
Fix NPE in a Trie flush
Browse files Browse the repository at this point in the history
  • Loading branch information
mkalinin committed Nov 6, 2017
1 parent 17a0d98 commit b3b6fc1
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ public Node(byte[] hashOrRlp) {

private Node(RLP.LList parsedRlp) {
this.parsedRlp = parsedRlp;
this.rlp = parsedRlp.getEncoded();
}

private Node(Object[] children) {
Expand Down
8 changes: 8 additions & 0 deletions ethereumj-core/src/main/java/org/ethereum/util/RLP.java
Original file line number Diff line number Diff line change
Expand Up @@ -710,6 +710,14 @@ public LList(byte[] rlp) {
this.rlp = rlp;
}

public byte[] getEncoded() {
byte encoded[][] = new byte[cnt][];
for (int i = 0; i < cnt; i++) {
encoded[i] = encodeElement(getBytes(i));
}
return encodeList(encoded);
}

public void add(int off, int len, boolean isList) {
offsets[cnt] = off;
lens[cnt] = isList ? (-1 - len) : len;
Expand Down
28 changes: 28 additions & 0 deletions ethereumj-core/src/test/java/org/ethereum/trie/TrieTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -1078,6 +1078,34 @@ public void testBugFix() throws ParseException, IOException, URISyntaxException
Hex.decode("00000000000000000000000000000000000000000000002f0000000000000000"));
}

@Test
public void testBugFix2() throws ParseException, IOException, URISyntaxException {

Source<byte[], byte[]> src = new HashMapDB<>();

// Create trie: root -> BranchNode (..., NodeValue (less than 32 bytes), ...)
TrieImpl trie = new TrieImpl(src);
trie.put(Hex.decode("0000000000000000000000000000000000000000000000000000000000000011"), Hex.decode("11"));
trie.put(Hex.decode("0000000000000000000000000000000000000000000000000000000000000022"), Hex.decode("22"));
trie.flush();

// Reset trie to refresh the nodes
trie = new TrieImpl(src, trie.getRootHash());

// Update trie: root -> dirty BranchNode (..., NodeValue (less than 32 bytes), ..., dirty NodeValue, ...)
trie.put(Hex.decode("0000000000000000000000000000000000000000000000000000000000000033"), Hex.decode("33"));

// BUG:
// In that case NodeValue (encoded as plain RLP list) isn't dirty
// while both rlp and hash fields are null, Node has been initialized with parsedRLP only
// Therefore any subsequent call to BranchNode.encode() fails with NPE

// FIX:
// Supply Node initialization with raw rlp value

assertEquals("36e350d9a1d9c02d5bc4539a05e51890784ea5d2b675a0b26725dbbdadb4d6e2", Hex.toHexString(trie.getRootHash()));
}

@Ignore
@Test
public void perfTestGet() {
Expand Down

0 comments on commit b3b6fc1

Please sign in to comment.