Ejemplo n.º 1
0
def signElement(elem: Element) -> Signature:
    if isinstance(elem, Verification):
        verif: SignedVerification = SignedVerification(elem.hash, elem.holder)
        verif.sign(elem.holder, PrivateKey(elem.holder))
        return verif.signature

    if isinstance(elem, SignedMeritRemovalVerificationPacket):
        return elem.signature

    if isinstance(elem, SendDifficulty):
        sendDiff: SignedSendDifficulty = SignedSendDifficulty(
            elem.difficulty, elem.nonce)
        sendDiff.sign(elem.holder, PrivateKey(elem.holder))
        return sendDiff.signature

    if isinstance(elem, DataDifficulty):
        dataDiff: SignedDataDifficulty = SignedDataDifficulty(
            elem.difficulty, elem.nonce)
        dataDiff.sign(elem.holder, PrivateKey(elem.holder))
        return dataDiff.signature

    if isinstance(elem, MeritRemoval):
        result: Signature = signElement(elem.e2)
        if not elem.partial:
            result = Signature.aggregate([result, signElement(elem.e1)])
        return result

    raise GenerationError(
        "Tried to sign an Element in a Block we didn't recognize the type of.")
Ejemplo n.º 2
0
    def __init__(
        self,
        version: int,
        last: bytes,
        contents: bytes,
        significant: int,
        sketchSalt: bytes,
        sketchCheck: bytes,
        miner: Union[int, bytes],
        time: int,
        proof: int = 0,
        signature: bytes = Signature().serialize()) -> None:
        self.version: int = version
        self.last: bytes = last
        self.contents: bytes = contents

        self.significant: int = significant
        self.sketchSalt: bytes = sketchSalt
        self.sketchCheck: bytes = sketchCheck

        self.newMiner: bool = isinstance(miner, bytes)
        if isinstance(miner, bytes):
            self.minerKey: bytes = miner
        else:
            self.minerNick: int = miner
        self.time: int = time
        self.proof: int = proof
        self.signature: bytes = signature

        self.rehash()
Ejemplo n.º 3
0
 def add(self, verif: SignedVerification) -> None:
     self.holders.append(verif.holder)
     if self.signature.isInf():
         self.signature = verif.signature
     else:
         self.signature = Signature.aggregate(
             [self.signature, verif.signature])
Ejemplo n.º 4
0
 def __init__(
     self,
     txHash: bytes,
     holders: List[int] = [],
     signature: Signature = Signature()) -> None:
     VerificationPacket.__init__(self, txHash, holders)
     self.signature: Signature = signature
Ejemplo n.º 5
0
 def __init__(self,
              difficulty: int,
              nonce: int = 0,
              holder: int = 0,
              signature: Signature = Signature()) -> None:
     SendDifficulty.__init__(self, difficulty, nonce, holder)
     self.signature: Signature = signature
Ejemplo n.º 6
0
 def __init__(self,
              e1: MeritRemovalElement,
              e2: MeritRemovalElement,
              holder: int = -1) -> None:
     PartialMeritRemoval.__init__(self, e1, e2, holder)
     self.partial = False
     self.se1: SignedElement = e1
     self.signature = Signature.aggregate([e1.signature, e2.signature])
Ejemplo n.º 7
0
    def fromSignedJSON(json: Dict[str, Any]) -> Any:
        holders: List[bytes] = []
        for holder in json["holders"]:
            holders.append(bytes.fromhex(holder))

        return SignedMeritRemovalVerificationPacket(
            SignedVerificationPacket(bytes.fromhex(json["hash"])), holders,
            Signature(bytes.fromhex(json["signature"])))
Ejemplo n.º 8
0
 def fromSignedJSON(
   json: Dict[str, Any]
 ) -> Any:
   return SignedDataDifficulty(
     json["difficulty"],
     json["nonce"],
     json["holder"],
     Signature(bytes.fromhex(json["signature"]))
   )
Ejemplo n.º 9
0
 def __init__(
     self,
     inputs: List[Tuple[bytes, int]],
     output: bytes,
     signature: bytes = Signature().serialize()) -> None:
     self.inputs: List[Tuple[bytes, int]] = inputs
     self.output: bytes = output
     self.amount: int = 0
     self.hash = blake2b(b'\1' + self.serializeInputs() + output,
                         digest_size=32).digest()
     self.signature: bytes = signature
Ejemplo n.º 10
0
Archivo: Claim.py Proyecto: Vyryn/Meros
    def __init__(
        self,
        inputs: List[Tuple[Mint, int]],
        output: bytes,
        signature: bytes = Signature().serialize()) -> None:
        self.inputs: List[Tuple[bytes, int]] = []
        self.amount: int = 0
        for txInput in inputs:
            self.inputs.append((txInput[0].hash, txInput[1]))
            self.amount += txInput[0].outputs[txInput[1]][1]

        self.output: bytes = output
        self.calculateHash()
        self.signature: bytes = signature
Ejemplo n.º 11
0
    def sign(self, privKeys: List[PrivateKey]) -> None:
        signatures: List[Signature] = [
            privKeys[0].sign(b'\1' + self.inputs[0][0] +
                             self.inputs[0][1].to_bytes(1, "big") +
                             self.output)
        ]

        for i in range(1, len(self.inputs)):
            signatures.append(
                privKeys[i].sign(b'\1' + self.inputs[i][0] +
                                 self.inputs[i][1].to_bytes(1, "big") +
                                 self.output))

        self.signature = Signature.aggregate(signatures).serialize()
        self.hash = blake2b(b'\1' + self.signature, digest_size=32).digest()
Ejemplo n.º 12
0
    def fromJSON(json: Dict[str, Any]) -> Any:
        packets: List[VerificationPacket] = []
        elements: List[Element] = []

        for packet in json["transactions"]:
            packets.append(
                VerificationPacket(bytes.fromhex(packet["hash"]),
                                   packet["holders"]))

        for element in json["elements"]:
            if element["descendant"] == "SendDifficulty":
                elements.append(SendDifficulty.fromJSON(element))
            elif element["descendant"] == "DataDifficulty":
                elements.append(DataDifficulty.fromJSON(element))

        return BlockBody(packets, elements,
                         Signature(bytes.fromhex(json["aggregate"])))
Ejemplo n.º 13
0
    def __init__(
        self,
        packets: List[VerificationPacket] = [],
        elements: List[Element] = [],
        aggregate: Signature = Signature()) -> None:
        self.packets: List[VerificationPacket] = sorted(
            list(packets), key=lambda packet: packet.hash[::-1])

        packetsMerkle: List[bytes] = []
        for packet in self.packets:
            packetsMerkle.append(
                blake2b(packet.prefix + packet.serialize(),
                        digest_size=32).digest())
        self.packetsContents: bytes = merkle(packetsMerkle)

        self.elements: List[Element] = list(elements)
        self.aggregate: Signature = aggregate
Ejemplo n.º 14
0
  def __init__(
    self,
    e1: Union[
      SignedVerification,
      SignedMeritRemovalVerificationPacket,
      SignedSendDifficulty,
      SignedDataDifficulty
    ],
    e2: Union[
      SignedVerification,
      SignedMeritRemovalVerificationPacket,
      SignedSendDifficulty,
      SignedDataDifficulty
    ],
    holder: int = -1
  ) -> None:
    PartialMeritRemoval.__init__(self, e1, e2, holder)
    self.partial = False

    self.se1: SignedElement = e1
    self.signature = Signature.aggregate([e1.signature, e2.signature])
Ejemplo n.º 15
0
def EightyEightTest(rpc: RPC) -> None:
    edPrivKey: Ristretto.SigningKey = Ristretto.SigningKey(b'\0' * 32)
    edPubKey: bytes = edPrivKey.get_verifying_key()

    blsPrivKey: PrivateKey = PrivateKey(0)
    blsPubKey: str = blsPrivKey.toPublicKey().serialize().hex()

    merit: Merit = Merit()
    dataFilter: SpamFilter = SpamFilter(5)

    #Handshake with the node.
    rpc.meros.liveConnect(merit.blockchain.blocks[0].header.hash)
    rpc.meros.syncConnect(merit.blockchain.blocks[0].header.hash)

    #Send the first Block.
    block: Block
    with open("e2e/Vectors/Merit/BlankBlocks.json", "r") as file:
        block = Block.fromJSON(json.loads(file.read())[0])
    merit.blockchain.add(block)
    rpc.meros.liveBlockHeader(block.header)
    rpc.meros.handleBlockBody(block)
    if MessageType(rpc.meros.live.recv()[0]) != MessageType.BlockHeader:
        raise TestError(
            "Meros didn't broadcast the Block Header it just added.")

    #Create two Datas.
    datas: List[Data] = [Data(bytes(32), edPubKey)]
    datas.append(Data(datas[0].hash, b"Hello there! General Kenobi."))

    for data in datas:
        #Sign them and have them beat the spam filter.
        data.sign(edPrivKey)
        data.beat(dataFilter)

        #Transmit them.
        rpc.meros.liveTransaction(data)

    #Verify both.
    verifs: List[SignedVerification] = [
        SignedVerification(datas[0].hash),
        SignedVerification(datas[1].hash)
    ]
    for verif in verifs:
        verif.sign(0, blsPrivKey)

    #Only transmit the second.
    rpc.meros.signedElement(verifs[1])
    sleep(1.5)

    #Verify the block template has no verifications.
    if bytes.fromhex(
            rpc.call("merit", "getBlockTemplate",
                     {"miner": blsPubKey})["header"])[36:68] != bytes(32):
        raise TestError("Block template has Verification Packets.")

    #Transmit the first signed verification.
    rpc.meros.signedElement(verifs[0])
    sleep(1.5)

    #Verify the block template has both verifications.
    template: Dict[str, Any] = rpc.call("merit", "getBlockTemplate",
                                        {"miner": blsPubKey})
    template["header"] = bytes.fromhex(template["header"])
    packets: List[VerificationPacket] = [
        VerificationPacket(datas[0].hash, [0]),
        VerificationPacket(datas[1].hash, [0])
    ]
    if template["header"][36:68] != BlockHeader.createContents(packets):
        raise TestError(
            "Block template doesn't have both Verification Packets.")

    #Mine the Block.
    block = Block(
        BlockHeader(
            0, block.header.hash, BlockHeader.createContents(packets),
            len(packets), template["header"][-43:-39],
            BlockHeader.createSketchCheck(template["header"][-43:-39],
                                          packets), 0,
            int.from_bytes(template["header"][-4:], byteorder="little")),
        BlockBody(
            packets, [],
            Signature.aggregate([verifs[0].signature, verifs[1].signature])))
    if block.header.serializeHash()[:-4] != template["header"]:
        raise TestError("Failed to recreate the header.")

    block.mine(blsPrivKey, merit.blockchain.difficulty())
    merit.blockchain.add(block)

    rpc.call(
        "merit", "publishBlock", {
            "id":
            template["id"],
            "header": (template["header"] +
                       block.header.proof.to_bytes(4, byteorder="little") +
                       block.header.signature).hex()
        })

    verifyBlockchain(rpc, merit.blockchain)
Ejemplo n.º 16
0
def EightyEightTest(
  rpc: RPC
) -> None:
  edPrivKey: ed25519.SigningKey = ed25519.SigningKey(b'\0' * 32)
  edPubKey: ed25519.VerifyingKey = edPrivKey.get_verifying_key()

  blsPrivKey: PrivateKey = PrivateKey(0)
  blsPubKey: str = blsPrivKey.toPublicKey().serialize().hex()

  file: IO[Any] = open("e2e/Vectors/Merit/BlankBlocks.json", "r")
  blocks: List[Dict[str, Any]] = json.loads(file.read())
  file.close()

  merit: Merit = Merit()
  dataFilter: SpamFilter = SpamFilter(5)

  #Handshake with the node.
  rpc.meros.liveConnect(merit.blockchain.blocks[0].header.hash)
  rpc.meros.syncConnect(merit.blockchain.blocks[0].header.hash)

  #Send the first Block.
  block: Block = Block.fromJSON(blocks[0])
  merit.blockchain.add(block)
  rpc.meros.liveBlockHeader(block.header)

  #Handle sync requests.
  reqHash: bytes = bytes()
  while True:
    msg: bytes = rpc.meros.sync.recv()
    if MessageType(msg[0]) == MessageType.BlockBodyRequest:
      reqHash = msg[1 : 33]
      if reqHash != block.header.hash:
        raise TestError("Meros asked for a Block Body that didn't belong to the Block we just sent it.")

      #Send the BlockBody.
      rpc.meros.blockBody(block)
      break

    else:
      raise TestError("Unexpected message sent: " + msg.hex().upper())

  if MessageType(rpc.meros.live.recv()[0]) != MessageType.BlockHeader:
    raise TestError("Meros didn't broadcast the Block Header it just added.")

  #Create two Datas.
  datas: List[Data] = [Data(bytes(32), edPubKey.to_bytes())]
  datas.append(Data(datas[0].hash, b"Hello there! General Kenobi."))

  for data in datas:
    #Sign them and have them beat the spam filter.
    data.sign(edPrivKey)
    data.beat(dataFilter)

    #Transmit them.
    rpc.meros.liveTransaction(data)

  #Verify both.
  verifs: List[SignedVerification] = [
    SignedVerification(datas[0].hash),
    SignedVerification(datas[1].hash)
  ]
  for verif in verifs:
    verif.sign(0, blsPrivKey)

  #Only transmit the second.
  rpc.meros.signedElement(verifs[1])
  sleep(0.5)

  #Verify the block template has no verifications.
  if bytes.fromhex(
    rpc.call("merit", "getBlockTemplate", [blsPubKey])["header"]
  )[36 : 68] != bytes(32):
    raise TestError("Block template has Verification Packets.")

  #Transmit the first signed verification.
  rpc.meros.signedElement(verifs[0])
  sleep(0.5)

  #Verify the block template has both verifications.
  template: Dict[str, Any] = rpc.call("merit", "getBlockTemplate", [blsPubKey])
  template["header"] = bytes.fromhex(template["header"])
  packets: List[VerificationPacket] = [VerificationPacket(datas[0].hash, [0]), VerificationPacket(datas[1].hash, [0])]
  if template["header"][36 : 68] != BlockHeader.createContents(packets):
    raise TestError("Block template doesn't have both Verification Packets.")

  #Mine the Block.
  block = Block(
    BlockHeader(
      0,
      block.header.hash,
      BlockHeader.createContents(packets),
      1,
      template["header"][-43 : -39],
      BlockHeader.createSketchCheck(template["header"][-43 : -39], packets),
      0,
      int.from_bytes(template["header"][-4:], byteorder="little")
    ),
    BlockBody(
      packets,
      [],
      Signature.aggregate([verifs[0].signature, verifs[1].signature])
    )
  )
  if block.header.serializeHash()[:-4] != template["header"]:
    raise TestError("Failed to recreate the header.")
  if block.body.serialize(
    block.header.sketchSalt,
    len(packets)
  ) != bytes.fromhex(template["body"]):
    raise TestError("Failed to recreate the body.")

  block.mine(blsPrivKey, merit.blockchain.difficulty())
  merit.blockchain.add(block)

  rpc.call(
    "merit",
    "publishBlock",
    [
      template["id"],
      (
        template["header"] +
        block.header.proof.to_bytes(4, byteorder="little") +
        block.header.signature +
        block.body.serialize(block.header.sketchSalt, len(packets))
      ).hex()
    ]
  )

  verifyBlockchain(rpc, merit.blockchain)
Ejemplo n.º 17
0
mr: SignedMeritRemoval = SignedMeritRemoval(verifs[1], verifs[2])

#Create a MeritRemoval with random keys.
packeted: SignedMeritRemoval = SignedMeritRemoval(
    SignedMeritRemovalVerificationPacket(
        SignedVerificationPacket(verifs[1].hash), [
            blsPubKey.serialize(),
            PrivateKey(blake2b(
                b'\1', digest_size=32).digest()).toPublicKey().serialize(),
            PrivateKey(blake2b(
                b'\2', digest_size=32).digest()).toPublicKey().serialize()
        ],
        Signature.aggregate([
            blsPrivKey.sign(verifs[1].signatureSerialize()),
            PrivateKey(blake2b(b'\1', digest_size=32).digest()).sign(
                verifs[1].signatureSerialize()),
            PrivateKey(blake2b(b'\2', digest_size=32).digest()).sign(
                verifs[1].signatureSerialize())
        ])),
    SignedMeritRemovalVerificationPacket(
        SignedVerificationPacket(verifs[2].hash), [
            blsPubKey.serialize(),
            PrivateKey(blake2b(
                b'\3', digest_size=32).digest()).toPublicKey().serialize(),
            PrivateKey(blake2b(
                b'\4', digest_size=32).digest()).toPublicKey().serialize()
        ],
        Signature.aggregate([
            blsPrivKey.sign(verifs[2].signatureSerialize()),
            PrivateKey(blake2b(b'\3', digest_size=32).digest()).sign(
                verifs[2].signatureSerialize()),
Ejemplo n.º 18
0
 def fromSignedJSON(json: Dict[str, Any]) -> Any:
     return SignedVerificationPacket(
         bytes.fromhex(json["hash"]), json["holders"],
         Signature(bytes.fromhex(json["signature"])))
Ejemplo n.º 19
0
    SignedDataDifficulty(2, 0)
]
for dataDiff in dataDiffs:
    dataDiff.sign(0, blsPrivKey)

for _ in range(2):
    block = Block(
        BlockHeader(
            0,
            blockchain.last(),
            #Used so the type checkers realize List[SignedDataDifficulty] is a viable List[Element].
            #pylint: disable=unnecessary-comprehension
            BlockHeader.createContents([], [e for e in dataDiffs]),
            0,
            bytes(4),
            bytes(32),
            0,
            blockchain.blocks[-1].header.time + 1200),
        #pylint: disable=unnecessary-comprehension
        BlockBody([], [e for e in dataDiffs],
                  Signature.aggregate([d.signature for d in dataDiffs])))
    block.mine(blsPrivKey, blockchain.difficulty())
    blockchain.add(block)

    #To verify the nonce isn't improperly set, add one more Data Difficulty with a nonce of 2.
    dataDiffs = [SignedDataDifficulty(4, 2)]
    dataDiffs[0].sign(0, blsPrivKey)

with open("e2e/Vectors/Merit/OutOfOrder/Elements.json", "w") as vectors:
    vectors.write(json.dumps(blockchain.toJSON()))
Ejemplo n.º 20
0
descendantVerif.sign(0, blsPrivKey)

#Convert the Verifications to packets.
packets: List[VerificationPacket] = [
    VerificationPacket(verifs[0].hash, [0]),
    VerificationPacket(verifs[1].hash, [0])
]

#Generate another 6 Blocks.
#Next block should have the packets.
block: Block = Block(
    BlockHeader(0, blockchain.last(), BlockHeader.createContents(packets), 1,
                bytes(4), BlockHeader.createSketchCheck(bytes(4), packets), 0,
                blockchain.blocks[-1].header.time + 1200),
    BlockBody(packets, [],
              Signature.aggregate([verifs[0].signature, verifs[1].signature])))
for _ in range(6):
    #Mine it.
    block.mine(blsPrivKey, blockchain.difficulty())

    #Add it.
    blockchain.add(block)
    print("Generated Prune Unaddable Block " + str(len(blockchain.blocks)) +
          ".")

    #Create the next Block.
    block = Block(
        BlockHeader(0, blockchain.last(), bytes(32), 1, bytes(4), bytes(32), 0,
                    blockchain.blocks[-1].header.time + 1200), BlockBody())

result: Dict[str, Any] = {
Ejemplo n.º 21
0
#Create a MeritRemoval out of the conflicting Verifications.
mr: SignedMeritRemoval = SignedMeritRemoval(verifs[1], verifs[2])

#Create a MeritRemoval with random keys.
packeted: SignedMeritRemoval = SignedMeritRemoval(
  SignedMeritRemovalVerificationPacket(
    SignedVerificationPacket(verifs[1].hash),
    [
      blsPubKey.serialize(),
      PrivateKey(1).toPublicKey().serialize(),
      PrivateKey(2).toPublicKey().serialize()
    ],
    Signature.aggregate([
      blsPrivKey.sign(verifs[1].signatureSerialize()),
      PrivateKey(1).sign(verifs[1].signatureSerialize()),
      PrivateKey(2).sign(verifs[1].signatureSerialize())
    ])
  ),
  SignedMeritRemovalVerificationPacket(
    SignedVerificationPacket(verifs[2].hash),
    [
      blsPubKey.serialize(),
      PrivateKey(3).toPublicKey().serialize(),
      PrivateKey(4).toPublicKey().serialize()
    ],
    Signature.aggregate(
      [
        blsPrivKey.sign(verifs[2].signatureSerialize()),
        PrivateKey(3).sign(verifs[2].signatureSerialize()),
        PrivateKey(4).sign(verifs[2].signatureSerialize())
Ejemplo n.º 22
0
 def __init__(self,
              txHash: bytes,
              holder: int = 0,
              signature: Signature = Signature()) -> None:
     Verification.__init__(self, txHash, holder)
     self.signature: Signature = signature
Ejemplo n.º 23
0
        data = Data(bytes(32), edPubKey.to_bytes())
    else:
        data = Data(data.hash, edPubKey.to_bytes())
    data.sign(edPrivKey)
    data.beat(dataFilter)
    transactions.add(data)

    svs.append(SignedVerification(data.hash))
    svs[-1].sign(0, blsPrivKey)
    packets.append(VerificationPacket(data.hash, [0]))

block = Block(
    BlockHeader(0, blockchain.last(), BlockHeader.createContents(packets), 1,
                bytes(4), BlockHeader.createSketchCheck(bytes(4), packets), 0,
                blockchain.blocks[-1].header.time + 1200),
    BlockBody(
        packets, [],
        Signature.aggregate(
            [svs[0].signature, svs[1].signature, svs[2].signature])))
block.mine(blsPrivKey, blockchain.difficulty())
blockchain.add(block)

vectors: IO[Any] = open("e2e/Vectors/Merit/HundredSeventyFive.json", "w")
vectors.write(
    json.dumps({
        "blockchain": blockchain.toJSON(),
        "transactions": transactions.toJSON(),
        "verification": svs[0].toSignedJSON()
    }))
vectors.close()
Ejemplo n.º 24
0
            if s not in packets:
                packets[s] = VerificationPacket(sends[s].hash, [])
            packets[s].holders.append(h)

            verif: SignedVerification = SignedVerification(sends[s].hash)
            verif.sign(h, blsPrivKeys[h])
            toAggregate.append(verif.signature)

    block: Block = Block(
        BlockHeader(
            0, blockchain.last(),
            BlockHeader.createContents(list(packets.values())), 1, bytes(4),
            BlockHeader.createSketchCheck(bytes(4), list(packets.values())),
            order[1], blockchain.blocks[-1].header.time + 1200),
        BlockBody(list(packets.values()), [],
                  Signature.aggregate(toAggregate)))

    miner: Union[bytes, int] = order[1]
    if isinstance(miner, bytes):
        for k in range(len(blsPubKeys)):
            if miner == blsPubKeys[k].serialize():
                block.mine(blsPrivKeys[k], blockchain.difficulty())
                break
    else:
        block.mine(blsPrivKeys[miner], blockchain.difficulty())

    blockchain.add(block)
    print("Generated Fifty Block " + str(len(blockchain.blocks) - 1) + ".")

#Generate another 5 Blocks.
for _ in range(5):
Ejemplo n.º 25
0
    send.sign(edPrivKey)
    send.beat(sendFilter)
    transactions.add(send)

    packets.append(VerificationPacket(send.hash, [i]))

    verif = SignedVerification(send.hash)
    verif.sign(i, blsPrivKeys[i])
    toAggregate.append(verif.signature)

#Archive the Packets and close the Epoch.
block = Block(
    BlockHeader(0, blockchain.last(), BlockHeader.createContents(packets), 1,
                bytes(4), BlockHeader.createSketchCheck(bytes(4), packets), 0,
                blockchain.blocks[-1].header.time + 1200),
    BlockBody(packets, [], Signature.aggregate(toAggregate)))
for _ in range(6):
    #Mine it.
    block.mine(blsPrivKeys[0], blockchain.difficulty())

    #Add it.
    blockchain.add(block)
    print("Generated Competing Block " + str(len(blockchain.blocks)) + ".")

    #Create the next Block.
    block = Block(
        BlockHeader(0, blockchain.last(), bytes(32), 1, bytes(4), bytes(32), 0,
                    blockchain.blocks[-1].header.time + 1200), BlockBody())

#Save the appended data (3 Blocks and 12 Sends).
result: Dict[str, Any] = {
Ejemplo n.º 26
0
    def finish(self, keepUnlocked: int, existing: Merit) -> Block:
        genesis: bytes = existing.blockchain.genesis
        prev: BlockHeader = existing.blockchain.blocks[-1].header
        diff: int = existing.blockchain.difficulty()

        #Create the signatures for every packet/element.
        signatures: List[Signature] = []
        for packet in self.packets:
            for holder in packet.holders:
                verif: SignedVerification = SignedVerification(
                    packet.hash, holder)
                verif.sign(holder, PrivateKey(holder))
                signatures.append(verif.signature)
        for element in self.elements:
            signatures.append(signElement(element))

        #Only add the Data Verification if:
        #1) We're supposed to make sure Merit Holders are always Unlocked
        #2) The last Block created a Data
        #3) The Merit Holder has Merit.
        if (keepUnlocked != 0) and (prev.last != genesis):
            #Create the Data from the last Block.
            blockData: Data = Data(genesis, prev.hash)

            #Create Verifications for said Data with every Private Key.
            #Ensures no one has their Merit locked.
            #pylint: disable=unnecessary-comprehension
            self.packets.append(VerificationPacket(blockData.hash, []))
            for i in range(keepUnlocked):
                if (
                        #Miners who are just being created don't have Merit.
                    ((i == (keepUnlocked - 1)) and
                     (isinstance(self.minerID, PrivateKey)))
                        or (existing.state.balances[i] == 0)):
                    continue

                self.packets[-1].holders.append(i)
                verif: SignedVerification = SignedVerification(
                    blockData.hash, i)
                verif.sign(i, PrivateKey(i))
                signatures.append(verif.signature)

            #Remove this packet if there's no holders.
            if not self.packets[-1].holders:
                del self.packets[-1]

        #Set the aggregate.
        aggregate = Signature.aggregate(signatures)

        #Create the actual Block.
        minerID: Union[bytes, int] = 0
        if isinstance(self.minerID, int):
            minerID = self.minerID
        else:
            minerID = self.minerID.toPublicKey().serialize()

        result: Block = Block(
            BlockHeader(
                0, prev.hash,
                BlockHeader.createContents(self.packets, self.elements),
                len(self.packets), bytes(4),
                BlockHeader.createSketchCheck(bytes(4), self.packets), minerID,
                self.time), BlockBody(self.packets, self.elements, aggregate))
        if isinstance(self.minerID, int):
            result.mine(PrivateKey(self.minerID), diff)
        else:
            result.mine(self.minerID, diff)
        return result
Ejemplo n.º 27
0
#Verify them.
verifs: List[List[SignedVerification]] = []
for data in datas:
    verifs.append(
        [SignedVerification(data.hash),
         SignedVerification(data.hash)])
    for v in range(2):
        verifs[-1][v].sign(v, blsPrivKeys[v])

#Create the packets.
packets: List[SignedVerificationPacket] = []
for packet in verifs:
    packets.append(
        SignedVerificationPacket(
            packet[0].hash, [0, 1],
            Signature.aggregate([packet[0].signature, packet[1].signature])))

#Create Blocks containing these packets.
for packet in packets:
    block = Block(
        BlockHeader(0, merit.blockchain.last(),
                    BlockHeader.createContents([packet]), 1, bytes(4),
                    BlockHeader.createSketchCheck(bytes(4), [packet]), 1,
                    merit.blockchain.blocks[-1].header.time + 1200),
        BlockBody([packet], [], packet.signature))
    block.mine(blsPrivKeys[1], merit.blockchain.difficulty())
    merit.add(block)
    print("Generated Aggregated Claim Block " +
          str(len(merit.blockchain.blocks) - 1) + ".")

#Generate another 5 Blocks to close the Epochs.
Ejemplo n.º 28
0
def TElementTest(
  rpc: RPC
) -> None:
  file: IO[Any] = open("e2e/Vectors/Merit/BlankBlocks.json", "r")
  blocks: List[Dict[str, Any]] = json.loads(file.read())
  file.close()
  merit: Merit = Merit()

  blsPrivKey: PrivateKey = PrivateKey(0)
  blsPubKey: str = blsPrivKey.toPublicKey().serialize().hex()

  #Handshake with the node.
  rpc.meros.liveConnect(merit.blockchain.blocks[0].header.hash)
  rpc.meros.syncConnect(merit.blockchain.blocks[0].header.hash)

  #Send the first Block.
  block: Block = Block.fromJSON(blocks[0])
  merit.blockchain.add(block)
  rpc.meros.liveBlockHeader(block.header)

  #Handle sync requests.
  reqHash: bytes = bytes()
  while True:
    msg: bytes = rpc.meros.sync.recv()
    if MessageType(msg[0]) == MessageType.BlockBodyRequest:
      reqHash = msg[1 : 33]
      if reqHash != block.header.hash:
        raise TestError("Meros asked for a Block Body that didn't belong to the Block we just sent it.")

      rpc.meros.blockBody(block)
      break

    else:
      raise TestError("Unexpected message sent: " + msg.hex().upper())

  if MessageType(rpc.meros.live.recv()[0]) != MessageType.BlockHeader:
    raise TestError("Meros didn't broadcast the Block Header it just added.")

  #Create and transmit a DataDifficulty.
  dataDiff: SignedDataDifficulty = SignedDataDifficulty(0, 0, 0)
  dataDiff.sign(0, blsPrivKey)
  rpc.meros.signedElement(dataDiff)
  sleep(0.5)

  #Verify the block template has the DataDifficulty.
  template: Dict[str, Any] = rpc.call("merit", "getBlockTemplate", [blsPubKey])
  template["header"] = bytes.fromhex(template["header"])
  if template["header"][36 : 68] != BlockHeader.createContents([], [dataDiff]):
    raise TestError("Block template doesn't have the Data Difficulty.")

  #Mine the Block.
  block = Block(
    BlockHeader(
      0,
      block.header.hash,
      BlockHeader.createContents([], [dataDiff]),
      1,
      template["header"][-43 : -39],
      BlockHeader.createSketchCheck(template["header"][-43 : -39], []),
      0,
      int.from_bytes(template["header"][-4:], byteorder="little"),
    ),
    BlockBody([], [dataDiff], dataDiff.signature)
  )
  if block.header.serializeHash()[:-4] != template["header"]:
    raise TestError("Failed to recreate the header.")
  if block.body.serialize(block.header.sketchSalt) != bytes.fromhex(template["body"]):
    raise TestError("Failed to recreate the body.")

  block.mine(blsPrivKey, merit.blockchain.difficulty())
  merit.blockchain.add(block)

  #Publish it.
  rpc.call(
    "merit",
    "publishBlock",
    [
      template["id"],
      (
        template["header"] +
        block.header.proof.to_bytes(4, byteorder="little") +
        block.header.signature +
        block.body.serialize(block.header.sketchSalt)
      ).hex()
    ]
  )

  #Create and transmit a new DataDifficulty.
  dataDiff = SignedDataDifficulty(3, 1, 0)
  dataDiff.sign(0, blsPrivKey)
  rpc.meros.signedElement(dataDiff)
  sleep(0.5)

  #Verify the block template has the DataDifficulty.
  template = rpc.call("merit", "getBlockTemplate", [blsPubKey])
  template["header"] = bytes.fromhex(template["header"])
  if template["header"][36 : 68] != BlockHeader.createContents([], [dataDiff]):
    raise TestError("Block template doesn't have the new Data Difficulty.")

  #Create and transmit a new DataDifficulty reusing an existing nonce.
  signatures: List[Signature] = [dataDiff.signature]
  dataDiff = SignedDataDifficulty(4, 1, 0)
  dataDiff.sign(0, blsPrivKey)
  signatures.append(dataDiff.signature)
  rpc.meros.signedElement(dataDiff)
  sleep(0.5)

  #Verify the block template has a MeritRemoval.
  mr: MeritRemoval = MeritRemoval(
    SignedDataDifficulty(3, 1, 0),
    SignedDataDifficulty(4, 1, 0),
    False
  )
  template = rpc.call("merit", "getBlockTemplate", [blsPubKey])
  template["header"] = bytes.fromhex(template["header"])
  if template["header"][36 : 68] != BlockHeader.createContents([], [mr]):
    raise TestError("Block template doesn't have the Merit Removal.")

  #Mine the Block.
  block = Block(
    BlockHeader(
      0,
      block.header.hash,
      BlockHeader.createContents([], [mr]),
      1,
      template["header"][-43 : -39],
      BlockHeader.createSketchCheck(template["header"][-43 : -39], []),
      0,
      int.from_bytes(template["header"][-4:], byteorder="little")
    ),
    BlockBody([], [mr], Signature.aggregate(signatures))
  )
  if block.header.serializeHash()[:-4] != template["header"]:
    raise TestError("Failed to recreate the header.")
  if block.body.serialize(block.header.sketchSalt) != bytes.fromhex(template["body"]):
    raise TestError("Failed to recreate the body.")

  block.mine(blsPrivKey, merit.blockchain.difficulty())
  merit.blockchain.add(block)

  rpc.call(
    "merit",
    "publishBlock",
    [
      template["id"],
      (
        template["header"] +
        block.header.proof.to_bytes(4, byteorder="little") +
        block.header.signature +
        block.body.serialize(block.header.sketchSalt)
      ).hex()
    ]
  )

  verifyBlockchain(rpc, merit.blockchain)
Ejemplo n.º 29
0
]

#Generate another 6 Blocks.
#Next block should have the packets.
block: Block = Block(
  BlockHeader(
    0,
    merit.blockchain.last(),
    BlockHeader.createContents(packets),
    1,
    bytes(4),
    BlockHeader.createSketchCheck(bytes(4), packets),
    0,
    merit.blockchain.blocks[-1].header.time + 1200
  ),
  BlockBody(packets, [], Signature.aggregate([firstVerif.signature, secondVerif.signature]))
)
for _ in range(6):
  #Mine it.
  block.mine(blsPrivKey, merit.blockchain.difficulty())

  #Add it.
  merit.add(block)
  print("Generated Competing Finalized Block " + str(len(merit.blockchain.blocks) - 1) + ".")

  #Create the next Block.
  block = Block(
    BlockHeader(
      0,
      merit.blockchain.last(),
      bytes(32),
Ejemplo n.º 30
0
    verifs[-1].sign(0, blsPrivKey)
    txs.append(Data(txs[-1].hash, b"\0"))
del txs[-1]

#Create the final Block.
#Done manually as it has invalid data.
packets: List[VerificationPacket] = [
    VerificationPacket(tx.hash, [0]) for tx in txs
]
blocks.append(
    Block(
        BlockHeader(0, blocks[0].header.hash,
                    BlockHeader.createContents(packets), 4, bytes(4),
                    BlockHeader.createSketchCheck(bytes(4), packets), 0, 2400),
        BlockBody(packets, [],
                  Signature.aggregate([verif.signature for verif in verifs]))))
#The difficulty either shouldn't change or should lower, hence why this works.
blocks[-1].header.mine(blsPrivKey, Merit().blockchain.difficulty())

#Only save the Verifications the test will use.
#Not a micro-opt on disk space; rather ensures this data isn't floating around to cause invalid testing methodology.
#This would optimally be inlined below with the vector write, yet pylint errors on the complex statement.
verifs = verifs[:2]

with open("e2e/Vectors/Merit/TwoHundredSeventyFour/MatchesHeaderQuantity.json",
          "w") as vectors:
    vectors.write(
        json.dumps({
            "blocks": [block.toJSON() for block in blocks],
            "transactions": [tx.toJSON() for tx in txs],
            "verifications": [verif.toSignedJSON() for verif in verifs]