<commit_before>package scorex.perma.consensus

import scorex.account.{Account, PrivateKeyAccount, PublicKeyAccount}
import scorex.block.{Block, BlockField}
import scorex.consensus.ConsensusModule
import scorex.crypto.SigningFunctions._
import scorex.crypto.ads.merkle.AuthDataBlock
import scorex.crypto.EllipticCurveImpl
import scorex.crypto.CryptographicHash.Digest
import scorex.perma.settings.Constants
import scorex.perma.settings.Constants._
import scorex.storage.Storage
import scorex.transaction.{BalanceSheet, BlockChain, TransactionModule}
import scorex.utils._

import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Future
import scala.util.Try

/**
  * Data and functions related to a consensus algo
  */
class PermaConsensusModule(rootHash: Array[Byte])
                          (implicit val authDataStorage: Storage[Long, AuthDataBlock[DataSegment]])
  extends ConsensusModule[PermaLikeConsensusBlockData] with ScorexLogging {

  val InitialDifficulty:BigInt = BigInt(Array.fill(36)(1: Byte))
  val GenesisCreator = new PublicKeyAccount(Array())
  val Version: Byte = 1
  val hash = Constants.hash

  implicit val consensusModule: ConsensusModule[PermaLikeConsensusBlockData] = this

  def miningReward(block: Block) = 1000000

  private def blockGenerator(block: Block) = block.signerDataField.value.generator

  def isValid[TT](block: Block)(implicit transactionModule: TransactionModule[TT]): Boolean = {
    val f = block.consensusDataField.asInstanceOf[PermaConsensusBlockField]
    val publicKey = blockGenerator(block).publicKey
    validate(publicKey, f.value.puz, f.value.difficulty, f.value.ticket, rootHash)
    //TODO check puz and previous block
  }

  /**
    * Fees could go to a single miner(forger) usually, but can go to many parties, e.g. see
    * Meni Rosenfeld's Proof-of-Activity proposal http://eprint.iacr.org/2014/452.pdf
    */
  def feesDistribution(block: Block): Map[Account, Long] =
    Map(blockGenerator(block) -> (miningReward(block) + block.transactions.map(_.fee).sum))

  /**
    * Get block producers(miners/forgers). Usually one miner produces a block, but in some proposals not
    * (see e.g. Meni Rosenfeld's Proof-of-Activity paper http://eprint.iacr.org/2014/452.pdf)
    */
  def generators(block: Block): Seq[Account] = Seq(blockGenerator(block))

  def blockScore(block: Block)(implicit transactionModule: TransactionModule[_]): BigInt = {
    ticketScore(block.consensusDataField.asInstanceOf[PermaConsensusBlockField].value.ticket)
  }

  def generateNextBlock[TT](account: PrivateKeyAccount)
                           (implicit transactionModule: TransactionModule[TT]): Future[Option[Block]] = Try {<commit_msg>Equals block score for all blocks<commit_after>package scorex.perma.consensus

import scorex.account.{Account, PrivateKeyAccount, PublicKeyAccount}
import scorex.block.{Block, BlockField}
import scorex.consensus.ConsensusModule
import scorex.crypto.SigningFunctions._
import scorex.crypto.ads.merkle.AuthDataBlock
import scorex.crypto.EllipticCurveImpl
import scorex.crypto.CryptographicHash.Digest
import scorex.perma.settings.Constants
import scorex.perma.settings.Constants._
import scorex.storage.Storage
import scorex.transaction.{BalanceSheet, BlockChain, TransactionModule}
import scorex.utils._

import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Future
import scala.util.Try

/**
  * Data and functions related to a consensus algo
  */
class PermaConsensusModule(rootHash: Array[Byte])
                          (implicit val authDataStorage: Storage[Long, AuthDataBlock[DataSegment]])
  extends ConsensusModule[PermaLikeConsensusBlockData] with ScorexLogging {

  val InitialDifficulty:BigInt = BigInt(Array.fill(36)(1: Byte))
  val GenesisCreator = new PublicKeyAccount(Array())
  val Version: Byte = 1
  val hash = Constants.hash

  implicit val consensusModule: ConsensusModule[PermaLikeConsensusBlockData] = this

  def miningReward(block: Block) = 1000000

  private def blockGenerator(block: Block) = block.signerDataField.value.generator

  def isValid[TT](block: Block)(implicit transactionModule: TransactionModule[TT]): Boolean = {
    val f = block.consensusDataField.asInstanceOf[PermaConsensusBlockField]
    val publicKey = blockGenerator(block).publicKey
    validate(publicKey, f.value.puz, f.value.difficulty, f.value.ticket, rootHash)
    //TODO check puz and previous block
  }

  /**
    * Fees could go to a single miner(forger) usually, but can go to many parties, e.g. see
    * Meni Rosenfeld's Proof-of-Activity proposal http://eprint.iacr.org/2014/452.pdf
    */
  def feesDistribution(block: Block): Map[Account, Long] =
    Map(blockGenerator(block) -> (miningReward(block) + block.transactions.map(_.fee).sum))

  /**
    * Get block producers(miners/forgers). Usually one miner produces a block, but in some proposals not
    * (see e.g. Meni Rosenfeld's Proof-of-Activity paper http://eprint.iacr.org/2014/452.pdf)
    */
  def generators(block: Block): Seq[Account] = Seq(blockGenerator(block))

  def blockScore(block: Block)(implicit transactionModule: TransactionModule[_]): BigInt = BigInt(1)

  def generateNextBlock[TT](account: PrivateKeyAccount)
                           (implicit transactionModule: TransactionModule[TT]): Future[Option[Block]] = Try {
{'fraction_non_alphanumeric': 0.10033695245226507, 'fraction_numerical': 0.009546986147510296, 'mean_word_length': 4.871428571428571, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, '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': '6990213', 'n_tokens_mistral': 1631, 'n_tokens_neox': 1561, 'n_words': 363}