use of org.aion.rlp.RLPList in project aion by aionnetwork.
the class AionContractDetailsImpl method decode.
@Override
public void decode(byte[] rlpCode) {
RLPList data = RLP.decode2(rlpCode);
RLPList rlpList = (RLPList) data.get(0);
RLPItem address = (RLPItem) rlpList.get(0);
RLPItem isExternalStorage = (RLPItem) rlpList.get(1);
RLPItem storage = (RLPItem) rlpList.get(2);
RLPElement code = rlpList.get(3);
RLPList keys = (RLPList) rlpList.get(4);
RLPItem storageRoot = (RLPItem) rlpList.get(5);
if (address.getRLPData() == null) {
this.address = Address.EMPTY_ADDRESS();
} else {
this.address = Address.wrap(address.getRLPData());
}
this.externalStorage = !Arrays.equals(isExternalStorage.getRLPData(), EMPTY_BYTE_ARRAY);
this.storageTrie.deserialize(storage.getRLPData());
if (code instanceof RLPList) {
for (RLPElement e : ((RLPList) code)) {
setCode(e.getRLPData());
}
} else {
setCode(code.getRLPData());
}
for (RLPElement key : keys) {
addKey(key.getRLPData());
}
if (externalStorage) {
storageTrie.withPruningEnabled(prune >= 0);
storageTrie.setRoot(storageRoot.getRLPData());
storageTrie.getCache().setDB(getExternalStorageDataSource());
}
externalStorage = (storage.getRLPData().length > detailsInMemoryStorageLimit) || externalStorage;
this.rlpEncoded = rlpCode;
}
use of org.aion.rlp.RLPList in project aion by aionnetwork.
the class RequestBlocks method decode.
/**
* Decodes a message into a block range request.
*
* @param message a {@code byte} array representing a request for a trie node.
* @return the decoded trie node request if valid or {@code null} when the decoding encounters
* invalid input
* @implNote Ensures that the components are not {@code null}.
*/
public static RequestBlocks decode(final byte[] message) {
if (message == null || message.length == 0) {
return null;
} else {
RLPList list = RLP.decode2(message);
if (list.get(0) instanceof RLPList) {
list = (RLPList) list.get(0);
} else {
return null;
}
if (list.size() != 4) {
return null;
} else {
// decode the requested type (number or hash)
byte value = new BigInteger(1, list.get(0).getRLPData()).byteValue();
if (value < 0 || value > 1) {
return null;
}
boolean isNumber = value == 1;
// decode the number of blocks requested
int count = new BigInteger(1, list.get(2).getRLPData()).intValue();
if (count <= 0) {
return null;
}
// decode the requested ordering of the block range
value = new BigInteger(1, list.get(3).getRLPData()).byteValue();
if (value < 0 || value > 1) {
return null;
}
boolean descending = value == 1;
if (isNumber) {
// decode the start block
long start = new BigInteger(1, list.get(1).getRLPData()).longValue();
if (start <= 0) {
return null;
}
// number based request
return new RequestBlocks(start, count, descending);
} else {
byte[] start = list.get(1).getRLPData();
if (start.length != HASH_SIZE) {
return null;
}
// hash based request
return new RequestBlocks(start, count, descending);
}
}
}
}
use of org.aion.rlp.RLPList in project aion by aionnetwork.
the class ResponseTrieData method decode.
/**
* Decodes a message into a trie node response.
*
* @param message a {@code byte} array representing a response to a trie node request.
* @return the decoded trie node response
* @implNote The decoder must return {@code null} if any of the component values are {@code
* null} or invalid.
*/
public static ResponseTrieData decode(final byte[] message) {
if (message == null || message.length == 0) {
return null;
} else {
RLPList list = RLP.decode2(message);
if (list.get(0) instanceof RLPList) {
list = (RLPList) list.get(0);
} else {
return null;
}
if (list.size() != TRIE_DATA_RESPONSE_COMPONENTS) {
return null;
} else {
// decode the key
byte[] hash = list.get(0).getRLPData();
if (hash.length != HASH_SIZE) {
return null;
}
// decode the value
byte[] value = list.get(1).getRLPData();
if (value.length == 0) {
return null;
}
// decode the referenced nodes
RLPElement referenced = list.get(2);
if (!(referenced instanceof RLPList)) {
return null;
}
Map<ByteArrayWrapper, byte[]> nodes = decodeReferencedNodes((RLPList) referenced);
if (nodes == null) {
return null;
}
// decode the db type
byte[] type = list.get(3).getRLPData();
DatabaseType dbType;
try {
dbType = DatabaseType.valueOf(new String(type));
} catch (IllegalArgumentException e) {
return null;
}
return new ResponseTrieData(ByteArrayWrapper.wrap(hash), value, nodes, dbType);
}
}
}
use of org.aion.rlp.RLPList in project aion by aionnetwork.
the class ResponseTrieData method decodeReferencedNodes.
/**
* Decodes the list of key-value pair encodings into a map representation.
*
* @return a map of all the key-value pair encodings
*/
private static Map<ByteArrayWrapper, byte[]> decodeReferencedNodes(RLPList referenced) {
if (referenced.isEmpty()) {
return Collections.emptyMap();
}
RLPList current;
byte[] hash, value;
Map<ByteArrayWrapper, byte[]> nodes = new HashMap<>();
for (RLPElement pair : referenced) {
if (!(pair instanceof RLPList)) {
return null;
}
current = (RLPList) pair;
// decode the key
hash = current.get(0).getRLPData();
if (hash.length != HASH_SIZE) {
return null;
}
// decode the value
value = current.get(1).getRLPData();
if (value.length == 0) {
return null;
}
nodes.put(ByteArrayWrapper.wrap(hash), value);
}
return nodes;
}
use of org.aion.rlp.RLPList in project aion by aionnetwork.
the class RequestTrieData method decode.
/**
* Decodes a message into a trie node request.
*
* @param message a {@code byte} array representing a request for a trie node.
* @return the decoded trie node request if valid or {@code null} when the decoding encounters
* invalid input
* @implNote Ensures that the components are not {@code null}.
*/
public static RequestTrieData decode(final byte[] message) {
if (message == null || message.length == 0) {
return null;
} else {
RLPList list = RLP.decode2(message);
if (list.get(0) instanceof RLPList) {
list = (RLPList) list.get(0);
} else {
return null;
}
if (list.size() != TRIE_DATA_REQUEST_COMPONENTS) {
return null;
} else {
// decode the key
byte[] hash = list.get(0).getRLPData();
if (hash.length != HASH_SIZE) {
return null;
}
// decode the db type
byte[] type = list.get(1).getRLPData();
DatabaseType dbType;
try {
dbType = DatabaseType.valueOf(new String(type));
} catch (IllegalArgumentException e) {
return null;
}
// decode the limit
int depth = new BigInteger(1, list.get(2).getRLPData()).intValue();
return new RequestTrieData(hash, dbType, depth);
}
}
}
Aggregations