public async Task <BlockExecutionResultCC> ExecuteBlock(IBlock block) { if (!await Prepare(block)) { return(BlockExecutionResultCC.Failed); } _logger?.Trace($"Executing block {block.GetHash()}"); var uncompressedPrivateKey = block.Header.P.ToByteArray(); var recipientKeyPair = ECKeyPair.FromPublicKey(uncompressedPrivateKey); var blockProducerAddress = recipientKeyPair.GetAddress(); _stateDictator.ChainId = block.Header.ChainId; _stateDictator.BlockHeight = block.Header.Index - 1; _stateDictator.BlockProducerAccountAddress = blockProducerAddress; var txs = new List <Transaction>(); try { txs = block.Body.TransactionList.ToList(); var txResults = await ExecuteTransactions(txs, Hash.LoadHex(NodeConfig.Instance.ChainId)); await InsertTxs(txs, txResults, block); var res = await UpdateState(block); var blockchain = _chainService.GetBlockChain(block.Header.ChainId); if (!res) { var txToRevert = await blockchain.RollbackOneBlock(); await _txPoolService.Revert(txToRevert); return(BlockExecutionResultCC.Failed); } await blockchain.AddBlocksAsync(new List <IBlock> { block }); await _binaryMerkleTreeManager.AddTransactionsMerkleTreeAsync(block.Body.BinaryMerkleTree, block.Header.ChainId, block.Header.Index); await _binaryMerkleTreeManager.AddSideChainTransactionRootsMerkleTreeAsync( block.Body.BinaryMerkleTreeForSideChainTransactionRoots, block.Header.ChainId, block.Header.Index); } catch (Exception e) { await Interrupt($"ExecuteBlock - Execution failed with exception {e}", txs, e); return(BlockExecutionResultCC.Failed); } return(BlockExecutionResultCC.Success); }
public void SignatureDecoding_Decode_ShouldBeEqualToOriginal() { // GenerareceivedKeyte the key pair ECKeyPair keyPair = new KeyPairGenerator().Generate(); // Get its byte array representation byte[] initialPublicKey = keyPair.GetEncodedPublicKey(compressed: true); // Reconstruct it and check if the key is the same ECKeyPair recipientKeyPair = ECKeyPair.FromPublicKey(initialPublicKey); byte[] receivedKey = recipientKeyPair.GetEncodedPublicKey(true); Assert.True(receivedKey.SequenceEqual(initialPublicKey)); }
public void SignAndVerifyTransaction() { byte[] fromAdress = CryptoHelpers.RandomFill(ADR_LENGTH); byte[] toAdress = CryptoHelpers.RandomFill(ADR_LENGTH); // Generate the key pair ECKeyPair keyPair = new KeyPairGenerator().Generate(); ; Transaction tx = new Transaction(); tx.From = Address.FromRawBytes(fromAdress); tx.To = Address.FromRawBytes(toAdress); tx.Sig = new Signature { P = ByteString.CopyFrom(keyPair.PublicKey.Q.GetEncoded()) }; // Serialize and hash the transaction Hash hash = tx.GetHash(); // Sign the hash ECSigner signer = new ECSigner(); ECSignature signature = signer.Sign(keyPair, hash.DumpByteArray()); // Update the signature tx.Sig.R = ByteString.CopyFrom(signature.R); tx.Sig.S = ByteString.CopyFrom(signature.S); // Serialize as for sending over the network byte[] serializedTx = tx.Serialize(); /**** broadcast/receive *****/ Transaction dTx = Transaction.Parser.ParseFrom(serializedTx); // Serialize and hash the transaction Hash dHash = dTx.GetHash(); byte[] uncompressedPrivKey = tx.Sig.P.ToByteArray(); ECKeyPair recipientKeyPair = ECKeyPair.FromPublicKey(uncompressedPrivKey); ECVerifier verifier = new ECVerifier(recipientKeyPair); Assert.True(verifier.Verify(dTx.GetSignature(), dHash.DumpByteArray())); }
/// <summary> /// Mainly for testing purposes, it's used for authentifying a node. Note that /// is doesn't launch the correponding event. /// </summary> /// <param name="handshakeMsg"></param> internal void AuthentifyWith(Handshake handshakeMsg) { if (handshakeMsg == null) { FireInvalidAuth(RejectReason.AuthInvalidHandshakeMsg); return; } _lastReceivedHandshake = handshakeMsg; try { if (handshakeMsg.Version != GlobalConfig.ProtocolVersion) { FireInvalidAuth(RejectReason.AuthWrongVersion); return; } DistantNodeKeyPair = ECKeyPair.FromPublicKey(handshakeMsg.PublicKey.ToByteArray()); if (DistantNodeKeyPair == null) { FireInvalidAuth(RejectReason.AuthInvalidKey); return; } // verify sig ECVerifier verifier = new ECVerifier(DistantNodeKeyPair); bool sigValid = verifier.Verify( new ECSignature(handshakeMsg.R.ToByteArray(), handshakeMsg.S.ToByteArray()), handshakeMsg.NodeInfo.ToByteArray()); if (!sigValid) { FireInvalidAuth(RejectReason.AuthInvalidSig); return; } } catch (Exception) { FireInvalidAuth(RejectReason.AuthInvalidKey); return; } IsAuthentified = true; }
public async Task Mine() { var chain = await _mock.CreateChain(); // create miner var keypair = new KeyPairGenerator().Generate(); var minerconfig = _mock.GetMinerConfig(chain.Id, 10, keypair.GetAddress().DumpByteArray()); ChainConfig.Instance.ChainId = chain.Id.DumpHex(); NodeConfig.Instance.NodeAccount = keypair.GetAddressHex(); var txPool = _mock.CreateTxPool(); txPool.Start(); var txs = CreateTx(chain.Id); foreach (var tx in txs) { await txPool.AddTransactionAsync(tx); } var manager = _mock.MinerClientManager(); var miner = _mock.GetMiner(minerconfig, txPool, manager); GrpcLocalConfig.Instance.ClientToSideChain = false; GrpcLocalConfig.Instance.WaitingIntervalInMillisecond = 10; NodeConfig.Instance.ECKeyPair = keypair; miner.Init(); var block = await miner.Mine(); Assert.NotNull(block); Assert.Equal(GlobalConfig.GenesisBlockHeight + 1, block.Header.Index); byte[] uncompressedPrivKey = block.Header.P.ToByteArray(); Address addr = Address.FromRawBytes(uncompressedPrivKey); Assert.Equal(minerconfig.CoinBase, addr); ECKeyPair recipientKeyPair = ECKeyPair.FromPublicKey(uncompressedPrivKey); ECVerifier verifier = new ECVerifier(recipientKeyPair); Assert.True(verifier.Verify(block.Header.GetSignature(), block.Header.GetHash().DumpByteArray())); }
public bool Verify(Transaction tx) { if (tx.P == null) { return(false); } var pubKey = tx.P.ToByteArray(); var addr = Address.FromRawBytes(pubKey); if (!addr.Equals(tx.From)) { return(false); } var keyPair = ECKeyPair.FromPublicKey(pubKey); var verifier = new ECVerifier(keyPair); return(verifier.Verify(tx.GetSignature(), tx.GetHash().DumpByteArray())); }
/// <summary> /// verify signature in tx /// </summary> /// <param name="tx"></param> /// <returns></returns> public static bool VerifySignature(this Transaction tx) { if (tx.Sig == null) { return(false); } byte[] uncompressedPrivKey = tx.P.ToByteArray(); var addr = Address.FromRawBytes(uncompressedPrivKey); // Hash addr = uncompressedPrivKey.Take(ECKeyPair.AddressLength).ToArray(); if (!addr.Equals(tx.From)) { return(false); } ECKeyPair recipientKeyPair = ECKeyPair.FromPublicKey(uncompressedPrivKey); ECVerifier verifier = new ECVerifier(recipientKeyPair); return(verifier.Verify(tx.GetSignature(), tx.GetHash().DumpByteArray())); }
private async Task <BlockValidationResult> DPoSValidation(IBlock block, IChainContext context) { // If the height of chain is 1, no need to check consensus validation if (block.Header.Index < GlobalConfig.GenesisBlockHeight + 2) { return(BlockValidationResult.Success); } // Get BP address var uncompressedPrivateKey = block.Header.P.ToByteArray(); var recipientKeyPair = ECKeyPair.FromPublicKey(uncompressedPrivateKey); var address = recipientKeyPair.GetAddress().DumpHex(); // Get the address of consensus contract var contractAccountHash = AddressHelpers.GetSystemContractAddress(context.ChainId, SmartContractType.AElfDPoS.ToString()); var timestampOfBlock = block.Header.Time; long roundId = 1; var updateTx = block.Body.TransactionList.Where(t => t.MethodName == ConsensusBehavior.UpdateAElfDPoS.ToString()) .ToList(); if (updateTx.Count > 0) { if (updateTx.Count > 1) { return(BlockValidationResult.IncorrectDPoSTxInBlock); } roundId = ((Round)ParamsPacker.Unpack(updateTx[0].Params.ToByteArray(), new[] { typeof(Round), typeof(Round), typeof(StringValue) })[1]).RoundId; } //Formulate an Executive and execute a transaction of checking time slot of this block producer TransactionTrace trace; var executive = await _smartContractService.GetExecutiveAsync(contractAccountHash, context.ChainId); try { var tx = GetTxToVerifyBlockProducer(contractAccountHash, NodeConfig.Instance.ECKeyPair, address, timestampOfBlock, roundId); if (tx == null) { return(BlockValidationResult.FailedToCheckConsensusInvalidation); } var tc = new TransactionContext { Transaction = tx }; await executive.SetTransactionContext(tc).Apply(); trace = tc.Trace; } finally { _smartContractService.PutExecutiveAsync(contractAccountHash, executive).Wait(); } //If failed to execute the transaction of checking time slot if (!trace.StdErr.IsNullOrEmpty()) { _logger.Trace("Failed to execute tx Validation: " + trace.StdErr); return(BlockValidationResult.FailedToCheckConsensusInvalidation); } var result = Int32Value.Parser.ParseFrom(trace.RetVal.ToByteArray()).Value; switch (result) { case 1: return(BlockValidationResult.NotBP); case 2: return(BlockValidationResult.InvalidTimeSlot); case 3: return(BlockValidationResult.SameWithCurrentRound); case 11: return(BlockValidationResult.ParseProblem); default: return(BlockValidationResult.Success); } }