co.rsk.peg.BridgeSerializationUtils.java Source code

Java tutorial

Introduction

Here is the source code for co.rsk.peg.BridgeSerializationUtils.java

Source

/*
 * This file is part of RskJ
 * Copyright (C) 2017 RSK Labs Ltd.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

package co.rsk.peg;

import co.rsk.crypto.Sha3Hash;
import org.apache.commons.lang3.tuple.Pair;
import co.rsk.bitcoinj.core.NetworkParameters;
import co.rsk.bitcoinj.core.Sha256Hash;
import co.rsk.bitcoinj.core.BtcTransaction;
import co.rsk.bitcoinj.core.UTXO;
import org.ethereum.util.RLP;
import org.ethereum.util.RLPList;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigInteger;
import java.util.*;

/**
 * Created by mario on 20/04/17.
 */
public class BridgeSerializationUtils {

    private BridgeSerializationUtils() {
    }

    public static byte[] serializeMap(SortedMap<Sha3Hash, BtcTransaction> map) {
        int ntxs = map.size();

        byte[][] bytes = new byte[ntxs * 2][];
        int n = 0;

        for (Map.Entry<Sha3Hash, BtcTransaction> entry : map.entrySet()) {
            bytes[n++] = RLP.encodeElement(entry.getKey().getBytes());
            bytes[n++] = RLP.encodeElement(entry.getValue().bitcoinSerialize());
        }

        return RLP.encodeList(bytes);
    }

    public static byte[] serializePairMap(SortedMap<Sha3Hash, Pair<BtcTransaction, Long>> map) {
        int ntxs = map.size();

        byte[][] bytes = new byte[ntxs * 3][];
        int n = 0;

        for (Map.Entry<Sha3Hash, Pair<BtcTransaction, Long>> entry : map.entrySet()) {
            bytes[n++] = RLP.encodeElement(entry.getKey().getBytes());
            bytes[n++] = RLP.encodeElement(entry.getValue().getLeft().bitcoinSerialize());
            bytes[n++] = RLP.encodeBigInteger(BigInteger.valueOf(entry.getValue().getRight()));
        }

        return RLP.encodeList(bytes);
    }

    public static byte[] serializeList(List<UTXO> list) throws IOException {
        int nutxos = list.size();

        byte[][] bytes = new byte[nutxos][];
        int n = 0;

        for (UTXO utxo : list) {
            ByteArrayOutputStream ostream = new ByteArrayOutputStream();
            utxo.serializeToStream(ostream);
            ostream.close();
            bytes[n++] = RLP.encodeElement(ostream.toByteArray());
        }

        return RLP.encodeList(bytes);
    }

    public static SortedMap<Sha3Hash, BtcTransaction> deserializeMap(byte[] data,
            NetworkParameters networkParameters) {
        SortedMap<Sha3Hash, BtcTransaction> map = new TreeMap<>();

        if (data == null || data.length == 0)
            return map;

        RLPList rlpList = (RLPList) RLP.decode2(data).get(0);

        int ntxs = rlpList.size() / 2;

        for (int k = 0; k < ntxs; k++) {
            Sha3Hash hash = new Sha3Hash(rlpList.get(k * 2).getRLPData());
            BtcTransaction tx = new BtcTransaction(networkParameters, rlpList.get(k * 2 + 1).getRLPData());
            map.put(hash, tx);
        }

        return map;
    }

    public static SortedMap<Sha3Hash, Pair<BtcTransaction, Long>> deserializePairMap(byte[] data,
            NetworkParameters networkParameters) {
        SortedMap<Sha3Hash, Pair<BtcTransaction, Long>> map = new TreeMap<>();

        if (data == null || data.length == 0)
            return map;

        RLPList rlpList = (RLPList) RLP.decode2(data).get(0);

        int ntxs = rlpList.size() / 3;

        for (int k = 0; k < ntxs; k++) {
            Sha3Hash hash = new Sha3Hash(rlpList.get(k * 3).getRLPData());
            BtcTransaction tx = new BtcTransaction(networkParameters, rlpList.get(k * 3 + 1).getRLPData());
            byte[] lkeyBytes = rlpList.get(k * 3 + 2).getRLPData();
            Long lkey = lkeyBytes == null ? 0 : (new BigInteger(1, lkeyBytes)).longValue();
            map.put(hash, Pair.of(tx, lkey));
        }

        return map;
    }

    public static List<UTXO> deserializeList(byte[] data) throws IOException {
        List<UTXO> list = new ArrayList<>();

        if (data == null || data.length == 0)
            return list;

        RLPList rlpList = (RLPList) RLP.decode2(data).get(0);

        int nutxos = rlpList.size();

        for (int k = 0; k < nutxos; k++) {
            byte[] utxoBytes = rlpList.get(k).getRLPData();
            InputStream istream = new ByteArrayInputStream(utxoBytes);
            UTXO utxo = new UTXO(istream);
            list.add(utxo);
        }

        return list;
    }

    public static byte[] serializeSet(SortedSet<Sha256Hash> set) {
        int nhashes = set.size();

        byte[][] bytes = new byte[nhashes][];
        int n = 0;

        for (Sha256Hash hash : set)
            bytes[n++] = RLP.encodeElement(hash.getBytes());

        return RLP.encodeList(bytes);
    }

    public static SortedSet<Sha256Hash> deserializeSet(byte[] data) {
        SortedSet<Sha256Hash> set = new TreeSet<>();

        if (data == null || data.length == 0)
            return set;

        RLPList rlpList = (RLPList) RLP.decode2(data).get(0);

        int nhashes = rlpList.size();

        for (int k = 0; k < nhashes; k++)
            set.add(Sha256Hash.wrap(rlpList.get(k).getRLPData()));

        return set;
    }
}