public RawEntryWithSaltedAndHashedEntry(PublicEntry rawEntry, byte[] salt, IHashProvider hashProvider) { RawEntry = rawEntry; SaltedAndHashedEntry = hashProvider.ComputeMultiHash(rawEntry, salt).ToArray(); }
public void STTransactionEntryDao_STTransactionEntry_Should_Be_Convertible() { var stTransactionEntryDao = GetMapper <PublicEntryDao>(); var pubKeyBytes = new byte[30]; new Random().NextBytes(pubKeyBytes); var original = new PublicEntry { Amount = 8855274.ToUint256ByteString(), Base = new BaseEntry { SenderPublicKey = pubKeyBytes.ToByteString(), TransactionFees = UInt256.Zero.ToUint256ByteString() } }; var transactionEntryDao = stTransactionEntryDao.ToDao(original); transactionEntryDao.Base.SenderPublicKey.Should().Be(pubKeyBytes.KeyToString()); transactionEntryDao.Amount.Should().Be(8855274.ToString()); var reconverted = transactionEntryDao.ToProtoBuff(); reconverted.Base.TransactionFees.ToUInt256().Should().Be(UInt256.Zero); reconverted.Should().Be(original); }
public int Compare(PublicEntry x, PublicEntry y) { if (ReferenceEquals(x, y)) { return(0); } if (ReferenceEquals(null, y)) { return(1); } if (ReferenceEquals(null, x)) { return(-1); } var feeComparison = x.TransactionFees.ToUInt256().CompareTo(y.TransactionFees.ToUInt256()); if (feeComparison != 0) { return(feeComparison); } var timeStampComparison = y.Timestamp.CompareTo(x.Timestamp); if (timeStampComparison != 0) { return(timeStampComparison); } return(ByteUtil.ByteListMinSizeComparer.Default.Compare(x.Signature.ToByteArray(), y.Signature.ToByteArray())); }
private ExecutionEnvironment PrepareEnv(PublicEntry entry, Address sender, Address recipient, StateUpdate stateUpdate, bool isPrecompile) { var value = entry.Amount.ToUInt256(); var machineCode = entry.IsValidDeploymentEntry ? entry.Data.ToByteArray() : null; var data = entry.IsValidDeploymentEntry ? null : entry.Data.ToByteArray(); var env = new ExecutionEnvironment { Value = value, TransferValue = value, Sender = sender, CodeSource = recipient, ExecutingAccount = recipient, CurrentBlock = stateUpdate, GasPrice = entry.GasPrice.ToUInt256(), InputData = data ?? new byte[0], CodeInfo = isPrecompile ? new CodeInfo(recipient) : machineCode == null ? _virtualMachine.GetCachedCodeInfo(recipient) : new CodeInfo(machineCode), Originator = sender }; return(env); }
public void PublicEntryDao_Should_Be_The_Same_When_Converted() { var pubKeyBytes = new byte[30]; new Random().NextBytes(pubKeyBytes); var original = new PublicEntry { Amount = new byte[] { 222, 11, 107, 58, 118, 64, 0, 0 }.ToByteString(), SenderAddress = pubKeyBytes.ToByteString(), Signature = new Signature { RawBytes = new byte[] { 0x0 }.ToByteString(), SigningContext = new SigningContext { NetworkType = NetworkType.Devnet, SignatureType = SignatureType.TransactionPublic } } }; var transactionEntryDao1 = original.ToDao <PublicEntry, PublicEntryDao>(_mapperProvider); var hashId1 = transactionEntryDao1.Id; var reconverted = transactionEntryDao1.ToProtoBuff <PublicEntryDao, PublicEntry>(_mapperProvider); var transactionEntryDao2 = reconverted.ToDao <PublicEntry, PublicEntryDao>(_mapperProvider); var hashId2 = transactionEntryDao2.Id; hashId1.Should().Be(hashId2); }
public void ValidateTransactionSignature_will_pass_with_valid_transaction_signature() { var subbedLogger = Substitute.For <ILogger>(); var cryptoContext = new FfiWrapper(); var transactionValidator = new TransactionValidator(subbedLogger, cryptoContext); // build a valid transaction var privateKey = cryptoContext.GeneratePrivateKey(); var validTransaction = new PublicEntry { SenderAddress = privateKey.GetPublicKey().Bytes.ToByteString() }; var signingContext = new SigningContext { NetworkType = NetworkType.Devnet, SignatureType = SignatureType.TransactionPublic }; var signature = new Signature { // sign an actual TransactionBroadcast object RawBytes = cryptoContext.Sign(privateKey, validTransaction.ToByteArray(), signingContext.ToByteArray()) .SignatureBytes.ToByteString(), SigningContext = signingContext }; validTransaction.Signature = signature; var result = transactionValidator.ValidateTransaction(validTransaction); result.Should().BeTrue(); }
TransactionValidator_ValidateTransactionSignature_returns_false_for_invalid_transaction_signature_verification() { var subbedLogger = Substitute.For <ILogger>(); var signatureResult = Substitute.For <ISignature>(); var subbedContext = new FakeContext(signatureResult, false); signatureResult.SignatureBytes.Returns(new byte[64]); var privateKey = Substitute.For <IPrivateKey>(); // raw un-signed tx message var validTransaction = new PublicEntry { SenderAddress = privateKey.GetPublicKey().Bytes.ToByteString() }; var txSig = new Signature { RawBytes = new byte[64] .ToByteString(), //random bytes that are not of a signed TransactionBroadcast Object SigningContext = new SigningContext { NetworkType = NetworkType.Devnet, SignatureType = SignatureType.TransactionPublic } }; var transactionValidator = new TransactionValidator(subbedLogger, subbedContext); validTransaction.Signature = txSig; var result = transactionValidator.ValidateTransaction(validTransaction); result.Should().BeFalse(); }
private bool ValidateTransactionSignature(PublicEntry transaction) { if (transaction.Signature.RawBytes == ByteString.Empty) { _logger.Error("Transaction signature is null"); return(false); } var transactionSignature = _cryptoContext.GetSignatureFromBytes(transaction.Signature.RawBytes.ToByteArray(), transaction.SenderAddress.ToByteArray()); var signingContext = transaction.Signature.SigningContext.ToByteArray(); // we need to verify the signature matches the message, but transactionBroadcast contains the signature and original data, // passing message+sig will mean your verifying an incorrect message and always return false, so just null the sig. var transactionClone = transaction.Clone(); transactionClone.Signature = null; if (_cryptoContext.Verify(transactionSignature, transactionClone.ToByteArray(), signingContext)) { return(true); } _logger.Information( "Transaction Signature {signature} invalid.", transactionSignature); return(false); }
/// <summary> /// This method calculates the basic gas cost of the <paramref name="entry" /> /// (excluding the cost of the VM execution). /// The intrinsic cost is calculated as 21000 base cost + the entry data cost that is a function /// of the number of bytes of data (and the cost of a single byte may differ between 0 bytes and non-0 bytes. /// </summary> /// <param name="entry"></param> /// <param name="releaseSpec"></param> /// <returns>Total intrinsic cost of the <paramref name="entry" /></returns> public static ulong CalculateIntrinsicGas(PublicEntry entry, IReleaseSpec releaseSpec) { ulong result = GasCostOf.Transaction; // the basic entry cost if (entry.Data != null) { // here is the difference between the 0 bytes and non-zero bytes cost // justified by a better compression level of zero bytes var txDataNonZeroGasCost = releaseSpec.IsEip2028Enabled ? GasCostOf.TxDataNonZeroEip2028 : GasCostOf.TxDataNonZero; var length = entry.Data.Length; for (var i = 0; i < length; i++) { result += entry.Data[i] == 0 ? GasCostOf.TxDataZero : (ulong)txDataNonZeroGasCost; } } if (entry.IsValidDeploymentEntry && releaseSpec.IsEip2Enabled) { result += GasCostOf.TxCreate; } return(result); }
public static Signature GenerateSignature(this PublicEntry publicEntry, ICryptoContext cryptoContext, IPrivateKey privateKey, SigningContext context) { return(GeneratePublicEntrySignature(publicEntry.Clone(), cryptoContext, privateKey, context)); }
/// <summary> /// @TODO we need to put this in some global logging system. /// </summary> /// <param name="entry"></param> /// <param name="reason"></param> private void TraceLogInvalidTx(PublicEntry entry, string reason) { if (_logger.IsEnabled(LogEventLevel.Verbose)) { _logger.Verbose("Invalid entry {entry} ({reason})", entry, reason); } }
public void STTransactionEntryDao_STTransactionEntry_Should_Be_Convertible() { var pubKeyBytes = new byte[30]; new Random().NextBytes(pubKeyBytes); var original = new PublicEntry { Amount = 8855274.ToUint256ByteString(), SenderAddress = pubKeyBytes.ToByteString(), TransactionFees = UInt256.Zero.ToUint256ByteString(), Signature = new Signature { RawBytes = new byte[] { 0x0 }.ToByteString(), SigningContext = new SigningContext { NetworkType = NetworkType.Devnet, SignatureType = SignatureType.TransactionPublic } }, Timestamp = Timestamp.FromDateTime(DateTime.UtcNow) }; var transactionEntryDao = original.ToDao <PublicEntry, PublicEntryDao>(_mapperProvider); transactionEntryDao.SenderAddress.Should().Be(pubKeyBytes.KeyToString()); transactionEntryDao.Amount.Should().Be(8855274.ToString()); var reconverted = transactionEntryDao.ToProtoBuff <PublicEntryDao, PublicEntry>(_mapperProvider); reconverted.TransactionFees.ToUInt256().Should().Be(UInt256.Zero); reconverted.Should().Be(original); }
TransactionValidator_ValidateTransactionSignature_returns_true_for_valid_transaction_signature_verification() { var subbedLogger = Substitute.For <ILogger>(); var signatureResult = Substitute.For <ISignature>(); var subbedContext = new FakeContext(signatureResult, true); signatureResult.SignatureBytes.Returns(new byte[64]); var transactionValidator = new TransactionValidator(subbedLogger, subbedContext); var privateKey = Substitute.For <IPrivateKey>(); var validTransaction = new PublicEntry { SenderAddress = privateKey.GetPublicKey().Bytes.ToByteString() }; var signature = new Signature { // sign an actual TransactionBroadcast object RawBytes = subbedContext.Sign(privateKey, validTransaction, new SigningContext()) .SignatureBytes.ToByteString(), SigningContext = new SigningContext { NetworkType = NetworkType.Devnet, SignatureType = SignatureType.TransactionPublic } }; validTransaction.Signature = signature; var result = transactionValidator.ValidateTransaction(validTransaction); result.Should().BeTrue(); }
public int Compare(PublicEntry x, PublicEntry y) { if (ReferenceEquals(x, y)) { return(0); } if (ReferenceEquals(null, y)) { return(1); } if (ReferenceEquals(null, x)) { return(-1); } var gasComparison = x.GasPrice.ToUInt256().CompareTo(y.GasPrice.ToUInt256()); if (gasComparison != 0) { return(gasComparison); } return(ByteUtil.ByteListMinSizeComparer.Default.Compare(x.Signature.ToByteArray(), y.Signature.ToByteArray())); }
private static void QuickFail(PublicEntry entry, ExecutionEnvironment env, ITxTracer txTracer) { // here we need to propagate back to Delta env.CurrentBlock.GasUsed += (long)entry.GasLimit; if (txTracer.IsTracingReceipt) { txTracer.MarkAsFailed(env.ExecutingAccount, (long)entry.GasLimit, Bytes.Empty, "invalid"); } }
public void Hashes_messages() { var hashProvider = _container.Resolve <IHashProvider>(); var entry = new PublicEntry(); var arrayHash = hashProvider.ComputeMultiHash(entry.ToByteArray()); var messageHash = hashProvider.ComputeMultiHash(entry); arrayHash.ToArray().Should().BeEquivalentTo(messageHash.ToArray()); }
private void UpdateLedgerAccountFromEntry(PublicEntry entry) { var pubKey = _cryptoContext.GetPublicKeyFromBytes(entry.Base.ReceiverPublicKey.ToByteArray()); //todo: get an address from the key using the Account class from Common lib var account = Accounts.Get(pubKey.Bytes.ToBase32()); //todo: a different logic for to and from entries account.Balance += entry.Amount.ToUInt256(); }
private bool ValidateSender(PublicEntry entry, ExecutionEnvironment env, ITxTracer txTracer) { if (env.Sender != null) { return(true); } TraceLogInvalidTx(entry, "SENDER_NOT_SPECIFIED"); QuickFail(entry, env, txTracer); return(false); }
/// <summary> /// Creates a delta for one off execution. /// </summary> public Delta CreateOneOffDelta(PublicEntry publicEntry) { Delta newDelta = Delta.Clone(); newDelta.PreviousDeltaDfsHash = Cid.ToArray().ToByteString(); newDelta.CoinbaseEntries.Clear(); newDelta.ConfidentialEntries.Clear(); newDelta.PublicEntries.Clear(); newDelta.PublicEntries.Add(publicEntry); return(newDelta); }
private (Address sender, Address recipient) ExtractSenderAndRecipient(PublicEntry entry) { var sender = entry.SenderAddress.ToAddress(); var recipient = entry.ReceiverAddress.ToAddress(); if (entry.IsValidDeploymentEntry) { recipient = ContractAddress.From(sender, _stateProvider.GetNonce(sender)); } return(sender, recipient); }
public void Hashes_messages_with_suffix() { var hashProvider = _container.Resolve <IHashProvider>(); var entry = new PublicEntry(); var suffix = new byte[1]; var arrayHash = hashProvider.ComputeMultiHash(entry.ToByteArray().Concat(suffix).ToArray()); var messageHash = hashProvider.ComputeMultiHash(entry, suffix); arrayHash.ToArray().Should().BeEquivalentTo(messageHash.ToArray()); }
private bool ValidateDeltaGasLimit(PublicEntry entry, ExecutionEnvironment env, ITxTracer txTracer) { if (entry.GasLimit <= (ulong)(env.CurrentBlock.GasLimit - env.CurrentBlock.GasUsed)) { return(true); } TraceLogInvalidTx(entry, $"BLOCK_GAS_LIMIT_EXCEEDED {entry.GasLimit.ToString()} > {env.CurrentBlock.GasLimit.ToString()} - {env.CurrentBlock.GasUsed.ToString()}"); QuickFail(entry, env, txTracer); return(false); }
private bool ValidateNonce(PublicEntry entry, ExecutionEnvironment env, ITxTracer txTracer) { if (entry.Nonce == _stateProvider.GetNonce(env.Sender)) { return(true); } TraceLogInvalidTx(entry, $"WRONG_TRANSACTION_NONCE: {entry.Nonce.ToString()} (expected {_stateProvider.GetNonce(env.Sender).ToString()})"); QuickFail(entry, env, txTracer); return(false); }
public void TestSigningForMessagesMethodEquivalence() { var privateKey = _wrapper.GeneratePrivateKey(); var message1 = new PublicEntry {Nonce = 123}; var message2 = new PublicEntry {Nonce = 34534908}; var expected = _wrapper.Sign(privateKey, message1.ToByteArray(), message2.ToByteArray()); var actual = _wrapper.Sign(privateKey, message1, message2); actual.SignatureBytes.Should().BeEquivalentTo(expected.SignatureBytes); actual.PublicKeyBytes.Should().BeEquivalentTo(expected.PublicKeyBytes); }
public void TestVerifyingForMessagesMethodEquivalence() { var privateKey = _wrapper.GeneratePrivateKey(); var message1 = new PublicEntry {Nonce = 123}; var context = new SigningContext {NetworkType = NetworkType.Mainnet}; var signature = _wrapper.Sign(privateKey, message1.ToByteArray(), context.ToByteArray()); var expected = _wrapper.Verify(signature, message1.ToByteArray(), context.ToByteArray()); var actual = _wrapper.Verify(signature, message1, context); actual.Should().Be(expected); }
private (Address sender, Address recipient) ExtractSenderAndRecipient(PublicEntry entry) { var sender = GetAccountAddress(entry.SenderAddress); var recipient = entry.TargetContract == null ? GetAccountAddress(entry.ReceiverAddress) : new Address(entry.TargetContract); if (entry.IsValidDeploymentEntry) { recipient = Address.OfContract(sender, _stateProvider.GetNonce(sender)); } return(sender, recipient); }
private static Signature GeneratePublicEntrySignature(PublicEntry publicEntry, ICryptoContext cryptoContext, IPrivateKey privateKey, SigningContext context) { publicEntry.Signature = null; var signatureBytes = cryptoContext.Sign(privateKey, publicEntry.ToByteArray(), context.ToByteArray()).SignatureBytes; return(new Signature { RawBytes = signatureBytes.ToByteString(), SigningContext = context }); }
public void TransactionValidator_ValidateTransactionSignature_returns_false_when_signature_is_null() { var subbedLogger = Substitute.For <ILogger>(); var subbedContext = Substitute.For <ICryptoContext>(); var transactionValidator = new TransactionValidator(subbedLogger, subbedContext); var invalidSignature = new Signature(); var invalidTransaction = new PublicEntry { Signature = invalidSignature }; var result = transactionValidator.ValidateTransaction(invalidTransaction); result.Should().BeFalse(); }
public static PublicEntry Sign(this PublicEntry publicEntry, ICryptoContext cryptoContext, IPrivateKey privateKey, SigningContext context) { var clone = publicEntry.Clone(); if (publicEntry.Signature?.RawBytes.Length == cryptoContext.SignatureLength) { Logger.Debug("The transaction was already signed, returning a clone."); return(clone); } clone.Signature = GeneratePublicEntrySignature(clone, cryptoContext, privateKey, context); return(clone); }
private bool ValidateSenderBalance(PublicEntry entry, ExecutionEnvironment env, ulong intrinsicGas, ITxTracer txTracer) { var senderBalance = _stateProvider.GetBalance(env.Sender); if (intrinsicGas * env.GasPrice + env.Value <= senderBalance) { return(true); } TraceLogInvalidTx(entry, $"INSUFFICIENT_SENDER_BALANCE: ({env.Sender})_BALANCE = {senderBalance.ToString()}"); QuickFail(entry, env, txTracer); return(false); }