All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.DNAProject.core.block.Block Maven / Gradle / Ivy

/*
 * Copyright (C) 2018 The DNA Authors
 * This file is part of The DNA library.
 *
 *  The DNA 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.
 *
 *  The DNA 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 The DNA.  If not, see .
 *
 */

package com.github.DNAProject.core.block;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;

import com.alibaba.fastjson.JSON;
import com.github.DNAProject.common.*;
import com.github.DNAProject.core.Inventory;
import com.github.DNAProject.core.InventoryType;
import com.github.DNAProject.core.payload.Bookkeeping;
import com.github.DNAProject.core.payload.DeployCode;
import com.github.DNAProject.core.payload.InvokeCode;
import com.github.DNAProject.core.transaction.Transaction;
import com.github.DNAProject.io.BinaryReader;
import com.github.DNAProject.io.BinaryWriter;
import com.github.DNAProject.io.Serializable;
import org.bouncycastle.math.ec.ECPoint;

/**
 * block
 */
public class Block extends Inventory {

    public int version;
    public UInt256 prevBlockHash;
    public UInt256 transactionsRoot;
    public UInt256 blockRoot;
    public int timestamp;
    public int height;
    public long consensusData;
    public byte[] consensusPayload;
    public Address nextBookkeeper;
    public String[] sigData;
    public byte[][] bookkeepers;
    public Transaction[] transactions;
    public UInt256 hash;
    private Block _header = null;

    public Block header() {
        if (isHeader()) {
            return this;
        }
        if (_header == null) {
            _header = new Block();
            _header.prevBlockHash = prevBlockHash;
            _header.transactionsRoot = this.transactionsRoot;
            _header.blockRoot = this.blockRoot;
            _header.timestamp = this.timestamp;
            _header.height = this.height;
            _header.consensusData = this.consensusData;
            _header.nextBookkeeper = this.nextBookkeeper;
            _header.sigData = this.sigData;
            _header.bookkeepers = this.bookkeepers;
            _header.transactions = new Transaction[0];
        }
        return _header;
    }

    @Override
    public InventoryType inventoryType() {
        return InventoryType.Block;
    }

    public boolean isHeader() {
        return transactions.length == 0;
    }

    @Override
    public void deserialize(BinaryReader reader) throws IOException {
        deserializeUnsigned(reader);
        int len = (int) reader.readVarInt();
        sigData = new String[len];
        for (int i = 0; i < len; i++) {
            this.sigData[i] = Helper.toHexString(reader.readVarBytes());
        }

        len = reader.readInt();
        transactions = new Transaction[len];
        for (int i = 0; i < transactions.length; i++) {
            transactions[i] = Transaction.deserializeFrom(reader);
        }
    }

    @Override
    public void deserializeUnsigned(BinaryReader reader) throws IOException {
        try {
            version = reader.readInt();
            prevBlockHash = reader.readSerializable(UInt256.class);
            transactionsRoot = reader.readSerializable(UInt256.class);
            blockRoot = reader.readSerializable(UInt256.class);
            timestamp = reader.readInt();
            height = reader.readInt();
            consensusData = Long.valueOf(reader.readLong());
            consensusPayload = reader.readVarBytes();
            nextBookkeeper = reader.readSerializable(Address.class);
            int len = (int) reader.readVarInt();
            bookkeepers = new byte[len][];
            for (int i = 0; i < len; i++) {
                this.bookkeepers[i] = reader.readVarBytes();
            }
            transactions = new Transaction[0];
        } catch (InstantiationException | IllegalAccessException ex) {
            throw new IOException(ex);
        }
    }

    @Override
    public void serialize(BinaryWriter writer) throws IOException {
        serializeUnsigned(writer);
        writer.writeVarInt(bookkeepers.length);
        for(int i=0;iHelper.toHexString(p)).toArray(Object[]::new));

        json.put("Header", head);
        json.put("Transactions", Arrays.stream(transactions).map(p -> {
            if (p instanceof InvokeCode) {
                return ((InvokeCode) p).json();
            } else if (p instanceof DeployCode) {
                return ((DeployCode) p).json();
            } else if (p instanceof Bookkeeping) {
                return ((Bookkeeping) p).json();
            } else {
                return p.json();
            }
        }).toArray(Object[]::new));
        return JSON.toJSONString(json);
    }

    public byte[] trim() {
        try (ByteArrayOutputStream ms = new ByteArrayOutputStream()) {
            try (BinaryWriter writer = new BinaryWriter(ms)) {
                serializeUnsigned(writer);
                writer.writeByte((byte) 1);
                writer.writeSerializableArray(Arrays.stream(transactions).map(p -> p.hash()).toArray(Serializable[]::new));
                writer.flush();
                return ms.toByteArray();
            }
        } catch (IOException ex) {
            throw new UnsupportedOperationException(ex);
        }
    }

    public static Block fromTrimmedData(byte[] data, int index, Function txSelector) throws IOException {
        Block block = new Block();
        try (ByteArrayInputStream ms = new ByteArrayInputStream(data, index, data.length - index)) {
            try (BinaryReader reader = new BinaryReader(ms)) {
                block.deserializeUnsigned(reader);
                reader.readByte();
                if (txSelector == null) {
                    block.transactions = new Transaction[0];
                } else {
                    block.transactions = new Transaction[(int) reader.readVarInt(0x10000000)];
                    for (int i = 0; i < block.transactions.length; i++) {
                        block.transactions[i] = txSelector.apply(reader.readSerializable(UInt256.class));
                    }
                }
            } catch (InstantiationException | IllegalAccessException ex) {
                throw new IOException(ex);
            }
        }
        return block;
    }
    @Override
    public boolean verify() {
        return true;
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy