<commit_before>package scorex.block

import java.util.Arrays

import com.google.common.primitives.{Bytes, Ints, Longs}
import ntp.NTP
import play.api.libs.json.{JsArray, JsObject, Json}
import scorex.BlockGenerator
import scorex.account.{PrivateKeyAccount, PublicKeyAccount}
import scorex.crypto.{Base58, Crypto}
import scorex.database.{PrunableBlockchainStorage, UnconfirmedTransactionsDatabaseImpl}
import scorex.transaction.Transaction.ValidationResult
import scorex.transaction.{GenesisTransaction, Transaction}
import scala.util.Try

case class BlockStub(version: Int, reference: Array[Byte], timestamp: Long, generatingBalance: Long,
                     generator: PublicKeyAccount, generatorSignature: Array[Byte]) {
  require(reference.length == Block.REFERENCE_LENGTH)
  require(generatingBalance > 0)
}

case class Block(version: Int, reference: Array[Byte], timestamp: Long, generatingBalance: Long,
                 generator: PublicKeyAccount, generatorSignature: Array[Byte],
                 transactions: List[Transaction], transactionsSignature: Array[Byte]) {
  import scorex.block.Block._

  def totalFee() = transactions.foldLeft(BigDecimal(0).setScale(8)) { case (fee, tx) => fee + tx.fee}

  def getTransaction(signature: Array[Byte]) = transactions.find(tx => tx.signature.sameElements(signature))

  def parent(): Option[Block] = PrunableBlockchainStorage.parent(this)

  def child(): Option[Block] = PrunableBlockchainStorage.child(this)

  def height(): Option[Int] = PrunableBlockchainStorage.heightOf(this)

  lazy val signature = Bytes.concat(generatorSignature, transactionsSignature)

  def toJson: JsObject =
    Json.obj("version" -> version,
      "reference" -> Base58.encode(reference),
      "timestamp" -> timestamp,
      "generatingBalance" -> generatingBalance,
      "generator" -> generator.address,
      "fee" -> totalFee(),
      "transactionsSignature" -> Base58.encode(transactionsSignature),
      "generatorSignature" -> Base58.encode(generatorSignature),
      "signature" -> Base58.encode(signature),
      "transactions" -> JsArray(transactions.map(_.toJson()))
    )

  def toBytes = {
    val versionBytes = Ints.toByteArray(version)
    val timestampBytes = Bytes.ensureCapacity(Longs.toByteArray(timestamp), 8, 0)
    val referenceBytes = Bytes.ensureCapacity(reference, REFERENCE_LENGTH, 0)
    val baseTargetBytes = Longs.toByteArray(generatingBalance)
    val generatorBytes = Bytes.ensureCapacity(generator.publicKey, GENERATOR_LENGTH, 0)
    val transactionCountBytes = Ints.toByteArray(transactions.size)
    val transactionBytes = transactions.foldLeft(Array[Byte]()) { case (txBytes, tx) =>
      Bytes.concat(txBytes, Ints.toByteArray(tx.dataLength), tx.toBytes())
    }

    Bytes.concat(versionBytes, timestampBytes, referenceBytes, baseTargetBytes, generatorBytes, transactionsSignature,
      generatorSignature, transactionCountBytes, transactionBytes)
  }

  def dataLength() = transactions.foldLeft(BASE_LENGTH) { case (len, tx) => len + 4 + tx.dataLength}

  //VALIDATE

  def isSignatureValid() = {
    val baseTargetBytes = Longs.toByteArray(generatingBalance).ensuring(_.size == Block.GENERATING_BALANCE_LENGTH)

    require(generator.publicKey.size == GENERATOR_LENGTH)
    val blockSignature = Bytes.concat(Arrays.copyOfRange(reference, 0, GENERATOR_SIGNATURE_LENGTH),
      baseTargetBytes,
      generator.publicKey)

    //VALIDATE TRANSACTIONS SIGNATURE
    val txsSignature = transactions.foldLeft(generatorSignature) { case (sig, tx) =>
      Bytes.concat(sig, tx.signature)
    }

    // todo: fix block signature validation!
     Crypto.verify(generatorSignature, blockSignature, generator.publicKey) &&
       Crypto.verify(transactionsSignature, txsSignature, generator.publicKey) &&
        transactions.forall(_.isSignatureValid())
  }
<commit_msg>fixed todo removed, formatting<commit_after>package scorex.block

import java.util.Arrays

import com.google.common.primitives.{Bytes, Ints, Longs}
import ntp.NTP
import play.api.libs.json.{JsArray, JsObject, Json}
import scorex.BlockGenerator
import scorex.account.{PrivateKeyAccount, PublicKeyAccount}
import scorex.crypto.{Base58, Crypto}
import scorex.database.{PrunableBlockchainStorage, UnconfirmedTransactionsDatabaseImpl}
import scorex.transaction.Transaction.ValidationResult
import scorex.transaction.{GenesisTransaction, Transaction}
import scala.util.Try

case class BlockStub(version: Int, reference: Array[Byte], timestamp: Long, generatingBalance: Long,
                     generator: PublicKeyAccount, generatorSignature: Array[Byte]) {
  require(reference.length == Block.REFERENCE_LENGTH)
  require(generatingBalance > 0)
}

case class Block(version: Int, reference: Array[Byte], timestamp: Long, generatingBalance: Long,
                 generator: PublicKeyAccount, generatorSignature: Array[Byte],
                 transactions: List[Transaction], transactionsSignature: Array[Byte]) {

  import scorex.block.Block._

  def totalFee() = transactions.foldLeft(BigDecimal(0).setScale(8)) { case (fee, tx) => fee + tx.fee}

  def getTransaction(signature: Array[Byte]) = transactions.find(tx => tx.signature.sameElements(signature))

  def parent(): Option[Block] = PrunableBlockchainStorage.parent(this)

  def child(): Option[Block] = PrunableBlockchainStorage.child(this)

  def height(): Option[Int] = PrunableBlockchainStorage.heightOf(this)

  lazy val signature = Bytes.concat(generatorSignature, transactionsSignature)

  def toJson: JsObject =
    Json.obj("version" -> version,
      "reference" -> Base58.encode(reference),
      "timestamp" -> timestamp,
      "generatingBalance" -> generatingBalance,
      "generator" -> generator.address,
      "fee" -> totalFee(),
      "transactionsSignature" -> Base58.encode(transactionsSignature),
      "generatorSignature" -> Base58.encode(generatorSignature),
      "signature" -> Base58.encode(signature),
      "transactions" -> JsArray(transactions.map(_.toJson()))
    )

  def toBytes = {
    val versionBytes = Ints.toByteArray(version)
    val timestampBytes = Bytes.ensureCapacity(Longs.toByteArray(timestamp), 8, 0)
    val referenceBytes = Bytes.ensureCapacity(reference, REFERENCE_LENGTH, 0)
    val baseTargetBytes = Longs.toByteArray(generatingBalance)
    val generatorBytes = Bytes.ensureCapacity(generator.publicKey, GENERATOR_LENGTH, 0)
    val transactionCountBytes = Ints.toByteArray(transactions.size)
    val transactionBytes = transactions.foldLeft(Array[Byte]()) { case (txBytes, tx) =>
      Bytes.concat(txBytes, Ints.toByteArray(tx.dataLength), tx.toBytes())
    }

    Bytes.concat(versionBytes, timestampBytes, referenceBytes, baseTargetBytes, generatorBytes, transactionsSignature,
      generatorSignature, transactionCountBytes, transactionBytes)
  }

  def dataLength() = transactions.foldLeft(BASE_LENGTH) { case (len, tx) => len + 4 + tx.dataLength}

  //VALIDATE

  def isSignatureValid() = {
    val baseTargetBytes = Longs.toByteArray(generatingBalance).ensuring(_.size == Block.GENERATING_BALANCE_LENGTH)

    require(generator.publicKey.size == GENERATOR_LENGTH)
    val blockSignature = Bytes.concat(Arrays.copyOfRange(reference, 0, GENERATOR_SIGNATURE_LENGTH),
      baseTargetBytes,
      generator.publicKey)

    //VALIDATE TRANSACTIONS SIGNATURE
    val txsSignature = transactions.foldLeft(generatorSignature) { case (sig, tx) =>
      Bytes.concat(sig, tx.signature)
    }

    Crypto.verify(generatorSignature, blockSignature, generator.publicKey) &&
      Crypto.verify(transactionsSignature, txsSignature, generator.publicKey) &&
      transactions.forall(_.isSignatureValid())
  }

{'fraction_non_alphanumeric': 0.10994901294286835, 'fraction_numerical': 0.004967969669237808, 'mean_word_length': 4.8800922367409685, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 35, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4540957', 'n_tokens_mistral': 2201, 'n_tokens_neox': 2144, 'n_words': 428}