Search in sources :

Example 91 with ByteArrayWrapper

use of org.aion.util.types.ByteArrayWrapper in project aion by aionnetwork.

the class Cache method commit.

private void commit(boolean flushCache) {
    // Don't try to commit if it isn't dirty
    if ((dataSource == null) || !this.isDirty) {
        // clear cache when flush requested
        if (flushCache) {
            this.nodes.clear();
        }
        return;
    }
    Map<byte[], byte[]> batch = new HashMap<>();
    List<byte[]> deleteBatch = new ArrayList<>();
    for (ByteArrayWrapper nodeKey : this.nodes.keySet()) {
        Node node = this.nodes.get(nodeKey);
        if (node == null || node.isDirty()) {
            byte[] value;
            if (node != null) {
                node.setDirty(false);
                value = node.getValue().encode();
            } else {
                value = null;
            }
            byte[] key = nodeKey.toBytes();
            batch.put(key, value);
        }
    }
    for (ByteArrayWrapper removedNode : removedNodes) {
        deleteBatch.add(removedNode.toBytes());
    }
    this.dataSource.putBatch(batch);
    this.dataSource.deleteBatch(deleteBatch);
    this.isDirty = false;
    if (flushCache) {
        this.nodes.clear();
    }
    this.removedNodes.clear();
}
Also used : ByteArrayWrapper(org.aion.util.types.ByteArrayWrapper) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) ArrayList(java.util.ArrayList)

Example 92 with ByteArrayWrapper

use of org.aion.util.types.ByteArrayWrapper in project aion by aionnetwork.

the class TrieImpl method serialize.

@VisibleForTesting
public byte[] serialize() {
    lock.lock();
    try {
        Map<ByteArrayWrapper, Node> map = getCache().getNodes();
        int keysTotalSize = 0;
        int valsTotalSize = 0;
        Set<ByteArrayWrapper> keys = map.keySet();
        for (ByteArrayWrapper key : keys) {
            Node node = map.get(key);
            if (node == null) {
                continue;
            }
            byte[] keyBytes = key.toBytes();
            keysTotalSize += keyBytes.length;
            byte[] valBytes = node.getValue().getData();
            valsTotalSize += valBytes.length + calcElementPrefixSize(valBytes);
        }
        byte[] root = null;
        try {
            ByteArrayOutputStream b = new ByteArrayOutputStream();
            ObjectOutputStream o = new ObjectOutputStream(b);
            o.writeObject(this.getRoot());
            root = b.toByteArray();
            root = RLP.encodeElement(root);
        } catch (IOException e) {
            e.printStackTrace();
        }
        byte[] keysHeader = RLP.encodeLongElementHeader(keysTotalSize);
        byte[] valsHeader = RLP.encodeListHeader(valsTotalSize);
        byte[] listHeader = RLP.encodeListHeader(keysTotalSize + keysHeader.length + valsTotalSize + valsHeader.length + root.length);
        byte[] rlpData = new byte[keysTotalSize + keysHeader.length + valsTotalSize + valsHeader.length + listHeader.length + root.length];
        // copy headers:
        // [ rlp_list_header, rlp_keys_header, rlp_keys, rlp_vals_header,
        // rlp_val]
        System.arraycopy(listHeader, 0, rlpData, 0, listHeader.length);
        System.arraycopy(keysHeader, 0, rlpData, listHeader.length, keysHeader.length);
        System.arraycopy(valsHeader, 0, rlpData, (listHeader.length + keysHeader.length + keysTotalSize), valsHeader.length);
        System.arraycopy(root, 0, rlpData, (listHeader.length + keysHeader.length + keysTotalSize + valsTotalSize + valsHeader.length), root.length);
        int k_1 = 0;
        int k_2 = 0;
        for (ByteArrayWrapper key : keys) {
            Node node = map.get(key);
            if (node == null) {
                continue;
            }
            // TODO: make internal wrapper operation
            System.arraycopy(key.toBytes(), 0, rlpData, (listHeader.length + keysHeader.length + k_1), key.length());
            k_1 += key.length();
            byte[] valBytes = RLP.encodeElement(node.getValue().getData());
            System.arraycopy(valBytes, 0, rlpData, listHeader.length + keysHeader.length + keysTotalSize + valsHeader.length + k_2, valBytes.length);
            k_2 += valBytes.length;
        }
        return rlpData;
    } finally {
        lock.unlock();
    }
}
Also used : ByteArrayWrapper(org.aion.util.types.ByteArrayWrapper) Node.isEmptyNode(org.aion.zero.impl.trie.Node.isEmptyNode) ByteArrayOutputStream(java.io.ByteArrayOutputStream) IOException(java.io.IOException) ObjectOutputStream(java.io.ObjectOutputStream) VisibleForTesting(com.google.common.annotations.VisibleForTesting)

Example 93 with ByteArrayWrapper

use of org.aion.util.types.ByteArrayWrapper in project aion by aionnetwork.

the class SyncMgr method validateAndAddBlocks.

/**
 * @param _nodeIdHashcode int
 * @param _displayId String
 * @param _bodies List<byte[]> Assemble and validate blocks batch and add batch to import queue
 *     from network response blocks bodies
 */
public void validateAndAddBlocks(int _nodeIdHashcode, String _displayId, final List<SharedRLPList> _bodies) {
    if (_bodies == null)
        return;
    log.debug("<received-bodies size={} node={}>", _bodies.size(), _displayId);
    // the requests are made such that the size varies to better map headers to bodies
    ByteArrayWrapper firstNodeRoot = ByteArrayWrapper.wrap(BlockUtil.getTxTrieRootFromUnsafeSource(_bodies.get(0)));
    List<BlockHeader> headers = syncHeaderRequestManager.matchAndDropHeaders(_nodeIdHashcode, _bodies.size(), firstNodeRoot);
    if (headers == null) {
        log.debug("<assemble-and-validate-blocks could not match headers for node={} size={} txTrieRoot={}>", _displayId, _bodies.size(), firstNodeRoot);
        return;
    }
    // assemble batch
    List<Block> blocks = new ArrayList<>(_bodies.size());
    Iterator<BlockHeader> headerIt = headers.iterator();
    Iterator<SharedRLPList> bodyIt = _bodies.iterator();
    while (headerIt.hasNext() && bodyIt.hasNext()) {
        Block block = BlockUtil.newBlockWithHeaderFromUnsafeSource(headerIt.next(), (SharedRLPList) bodyIt.next().get(0));
        if (block == null) {
            log.debug("<assemble-and-validate-blocks node={} size={}>", _displayId, _bodies.size());
            break;
        } else {
            blocks.add(block);
        }
    }
    int m = blocks.size();
    if (m == 0) {
        return;
    }
    log.debug("<assembled-blocks from={} size={} node={}>", blocks.get(0).getNumber(), blocks.size(), _displayId);
    // add batch
    syncExecutors.execute(() -> filterBlocks(new BlocksWrapper(_nodeIdHashcode, _displayId, blocks)));
}
Also used : ByteArrayWrapper(org.aion.util.types.ByteArrayWrapper) ArrayList(java.util.ArrayList) Block(org.aion.zero.impl.types.Block) BlockHeader(org.aion.zero.impl.types.BlockHeader) SharedRLPList(org.aion.rlp.SharedRLPList)

Example 94 with ByteArrayWrapper

use of org.aion.util.types.ByteArrayWrapper 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);
        }
    }
}
Also used : ByteArrayWrapper(org.aion.util.types.ByteArrayWrapper) DatabaseType(org.aion.zero.impl.sync.DatabaseType) RLPElement(org.aion.rlp.RLPElement) RLPList(org.aion.rlp.RLPList)

Example 95 with ByteArrayWrapper

use of org.aion.util.types.ByteArrayWrapper 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;
}
Also used : ByteArrayWrapper(org.aion.util.types.ByteArrayWrapper) HashMap(java.util.HashMap) RLPElement(org.aion.rlp.RLPElement) RLPList(org.aion.rlp.RLPList)

Aggregations

ByteArrayWrapper (org.aion.util.types.ByteArrayWrapper)130 Test (org.junit.Test)51 HashMap (java.util.HashMap)39 ArrayList (java.util.ArrayList)33 AionAddress (org.aion.types.AionAddress)26 Block (org.aion.zero.impl.types.Block)24 Map (java.util.Map)20 BigInteger (java.math.BigInteger)14 MiningBlock (org.aion.zero.impl.types.MiningBlock)14 IOException (java.io.IOException)13 MockDB (org.aion.db.impl.mockdb.MockDB)13 DataWord (org.aion.util.types.DataWord)13 PooledTransaction (org.aion.base.PooledTransaction)11 List (java.util.List)10 AionTransaction (org.aion.base.AionTransaction)10 Properties (java.util.Properties)8 HashSet (java.util.HashSet)5 Optional (java.util.Optional)5 ECKey (org.aion.crypto.ECKey)5 RLPElement (org.aion.rlp.RLPElement)5