Add serialization functionality to NodeDataRequest (#724)

Signed-off-by: Adrian Sutton <adrian.sutton@consensys.net>
pull/2/head
mbaxter 6 years ago committed by GitHub
parent a5afe34e34
commit b39731fa95
  1. 2
      ethereum/eth/src/main/java/tech/pegasys/pantheon/ethereum/eth/sync/worldstate/AccountTrieNodeDataRequest.java
  2. 2
      ethereum/eth/src/main/java/tech/pegasys/pantheon/ethereum/eth/sync/worldstate/CodeNodeDataRequest.java
  3. 52
      ethereum/eth/src/main/java/tech/pegasys/pantheon/ethereum/eth/sync/worldstate/NodeDataRequest.java
  4. 42
      ethereum/eth/src/main/java/tech/pegasys/pantheon/ethereum/eth/sync/worldstate/RequestType.java
  5. 2
      ethereum/eth/src/main/java/tech/pegasys/pantheon/ethereum/eth/sync/worldstate/StorageTrieNodeDataRequest.java
  6. 2
      ethereum/eth/src/main/java/tech/pegasys/pantheon/ethereum/eth/sync/worldstate/TrieNodeDataRequest.java
  7. 59
      ethereum/eth/src/test/java/tech/pegasys/pantheon/ethereum/eth/sync/worldstate/NodeDataRequestTest.java

@ -27,7 +27,7 @@ import java.util.List;
class AccountTrieNodeDataRequest extends TrieNodeDataRequest {
AccountTrieNodeDataRequest(final Hash hash) {
super(Kind.ACCOUNT_TRIE_NODE, hash);
super(RequestType.ACCOUNT_TRIE_NODE, hash);
}
@Override

@ -22,7 +22,7 @@ import java.util.stream.Stream;
class CodeNodeDataRequest extends NodeDataRequest {
CodeNodeDataRequest(final Hash hash) {
super(Kind.CODE, hash);
super(RequestType.CODE, hash);
}
@Override

@ -13,24 +13,22 @@
package tech.pegasys.pantheon.ethereum.eth.sync.worldstate;
import tech.pegasys.pantheon.ethereum.core.Hash;
import tech.pegasys.pantheon.ethereum.rlp.RLP;
import tech.pegasys.pantheon.ethereum.rlp.RLPInput;
import tech.pegasys.pantheon.ethereum.rlp.RLPOutput;
import tech.pegasys.pantheon.ethereum.worldstate.WorldStateStorage;
import tech.pegasys.pantheon.util.bytes.BytesValue;
import java.util.stream.Stream;
abstract class NodeDataRequest {
public enum Kind {
ACCOUNT_TRIE_NODE,
STORAGE_TRIE_NODE,
CODE
}
public abstract class NodeDataRequest {
private final Kind kind;
private final RequestType requestType;
private final Hash hash;
private BytesValue data;
protected NodeDataRequest(final Kind kind, final Hash hash) {
this.kind = kind;
protected NodeDataRequest(final RequestType requestType, final Hash hash) {
this.requestType = requestType;
this.hash = hash;
}
@ -46,8 +44,40 @@ abstract class NodeDataRequest {
return new CodeNodeDataRequest(hash);
}
public Kind getKind() {
return kind;
public static BytesValue serialize(final NodeDataRequest request) {
return RLP.encode(request::writeTo);
}
public static NodeDataRequest deserialize(final BytesValue encoded) {
RLPInput in = RLP.input(encoded);
in.enterList();
RequestType requestType = RequestType.fromValue(in.readByte());
Hash hash = Hash.wrap(in.readBytes32());
in.leaveList();
switch (requestType) {
case ACCOUNT_TRIE_NODE:
return createAccountDataRequest(hash);
case STORAGE_TRIE_NODE:
return createStorageDataRequest(hash);
case CODE:
return createCodeRequest(hash);
default:
throw new IllegalArgumentException(
"Unable to deserialize provided data into a valid "
+ NodeDataRequest.class.getSimpleName());
}
}
private void writeTo(final RLPOutput out) {
out.startList();
out.writeByte(requestType.getValue());
out.writeBytesValue(hash);
out.endList();
}
public RequestType getRequestType() {
return requestType;
}
public Hash getHash() {

@ -0,0 +1,42 @@
/*
* Copyright 2019 ConsenSys AG.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/
package tech.pegasys.pantheon.ethereum.eth.sync.worldstate;
public enum RequestType {
ACCOUNT_TRIE_NODE((byte) 1),
STORAGE_TRIE_NODE((byte) 2),
CODE((byte) 3);
private final byte value;
RequestType(final byte value) {
this.value = value;
}
public byte getValue() {
return value;
}
public static RequestType fromValue(final byte value) {
switch (value) {
case (byte) 1:
return ACCOUNT_TRIE_NODE;
case (byte) 2:
return STORAGE_TRIE_NODE;
case (byte) 3:
return CODE;
default:
throw new IllegalArgumentException("Invalid value supplied");
}
}
}

@ -24,7 +24,7 @@ import java.util.List;
class StorageTrieNodeDataRequest extends TrieNodeDataRequest {
StorageTrieNodeDataRequest(final Hash hash) {
super(Kind.STORAGE_TRIE_NODE, hash);
super(RequestType.STORAGE_TRIE_NODE, hash);
}
@Override

@ -24,7 +24,7 @@ abstract class TrieNodeDataRequest extends NodeDataRequest {
private static final TrieNodeDecoder nodeDecoder = TrieNodeDecoder.create();
TrieNodeDataRequest(final Kind kind, final Hash hash) {
TrieNodeDataRequest(final RequestType kind, final Hash hash) {
super(kind, hash);
}

@ -0,0 +1,59 @@
/*
* Copyright 2019 ConsenSys AG.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/
package tech.pegasys.pantheon.ethereum.eth.sync.worldstate;
import static org.assertj.core.api.Assertions.assertThat;
import tech.pegasys.pantheon.ethereum.core.BlockDataGenerator;
import org.junit.Test;
public class NodeDataRequestTest {
@Test
public void serializesAccountTrieNodeRequests() {
BlockDataGenerator gen = new BlockDataGenerator(0);
AccountTrieNodeDataRequest request = NodeDataRequest.createAccountDataRequest(gen.hash());
NodeDataRequest sedeRequest = serializeThenDeserialize(request);
assertRequestsEquals(sedeRequest, request);
assertThat(sedeRequest).isInstanceOf(AccountTrieNodeDataRequest.class);
}
@Test
public void serializesStorageTrieNodeRequests() {
BlockDataGenerator gen = new BlockDataGenerator(0);
StorageTrieNodeDataRequest request = NodeDataRequest.createStorageDataRequest(gen.hash());
NodeDataRequest sedeRequest = serializeThenDeserialize(request);
assertRequestsEquals(sedeRequest, request);
assertThat(sedeRequest).isInstanceOf(StorageTrieNodeDataRequest.class);
}
@Test
public void serializesCodeRequests() {
BlockDataGenerator gen = new BlockDataGenerator(0);
CodeNodeDataRequest request = NodeDataRequest.createCodeRequest(gen.hash());
NodeDataRequest sedeRequest = serializeThenDeserialize(request);
assertRequestsEquals(sedeRequest, request);
assertThat(sedeRequest).isInstanceOf(CodeNodeDataRequest.class);
}
private NodeDataRequest serializeThenDeserialize(final NodeDataRequest request) {
return NodeDataRequest.deserialize(NodeDataRequest.serialize(request));
}
private void assertRequestsEquals(final NodeDataRequest actual, final NodeDataRequest expected) {
assertThat(actual.getRequestType()).isEqualTo(expected.getRequestType());
assertThat(actual.getHash()).isEqualTo(expected.getHash());
assertThat(actual.getData()).isEqualTo(expected.getData());
}
}
Loading…
Cancel
Save