public static NotificationMessage CreateSignedNewLedgerNotification(SignedLedger ledger)
 {
     return(CreateNotification(new API.Notifications.SignedNewLedger
     {
         Ledger = ByteStreamConverter.ToBase64 <ByteStream>(stream => { stream.Write(new SignedNewLedger(ledger)); })
     }));
 }
        // call from command
        public void SetNextLedger(SignedLedger signed, Action onFinish)
        {
            if (!ValidateSignedLedgerInternal(signed))
            {
                return;
            }

            if (!ValidateSignatures(signed))
            {
                return;
            }

            try
            {
                // wait for other thread
                LedgerService.State.SetAndWait(LedgerStatus.Updating); // TODO really call from here?
                SetNextLedger(signed);
                onFinish.Call();
            }
            finally
            {
                // wait for other thread
                LedgerService.State.SetAndWait(LedgerStatus.Updated); // TODO really call from here?
            }
        }
示例#3
0
            private SignedLedger GetLedger()
            {
                var light = new LedgerLight(
                    ledgerService.LedgerManager.GetNextHeight(),
                    DateTime.Now.ToUnixTimestamp() + 1, // TODO ? ledgerService.LedgerManager.GetLedgerBeginTime() + 10,
                    ledgerService.LedgerManager.GetLastLedgerHash(),
                    ProtocolVersion.CURRENT_VERSION);

                var block = Block.CreateBlock(light.Height, pendingTransactions);

                var poststate = new PostStateHolder(ledgerService.LedgerManager.LedgerState, ledgerService.LedgerManager.GetNextHeight());

                foreach (var transaction in pendingTransactions)
                {
                    if (!poststate.ProcessTransaction(transaction))
                    {
                        return(null);
                    }
                }

                var finalized = poststate.Finalize(light.Version);

                var ledger = new Ledger(light, block, ledgerService.LedgerManager.GetMerkleRootHash(finalized, light.Version));
                var signed = new SignedLedger(ledger);

                validator.SignLedger(signed, NodeConfiguration.GetNetwork());

                return(signed);
            }
 public static GetSignedLedgerResponse CreateGetSignedLedgerResponse(SignedLedger signed = null)
 {
     return(new GetSignedLedgerResponse
     {
         Ledger = signed == null ? null : ToBase64 <ByteStream>(stream => { stream.Write(signed); })
     });
 }
示例#5
0
 private byte[] GetSignedLedgerBytes(SignedLedger signedLedger)
 {
     using (var stream = new ByteStream())
     {
         stream.Write(signedLedger);
         return(Zipper.Zip(stream.GetBytes()));
     }
 }
示例#6
0
        private void BroadcastNewLedger(SignedLedger signedLedger)
        {
            var message = NotificationHelper.CreateSignedNewLedgerNotification(signedLedger);

            // broadcast the hash of the new ledger with the signature.
            BlockchainChannel.Broadcast(message);
            Logger.Log("Broadcast Signed New Ledger");
        }
        private bool ValidateSignedLedgerInternal(SignedLedger signed)
        {
            if (needSetInitialLedger)
            {
                return(true);
            }

            return(ValidateSignedLedger(signed));
        }
示例#8
0
 public static void SaveLedger(SignedLedger signed, string path)
 {
     using (var stream = new ByteStream())
     {
         stream.Write(signed);
         var bytes = stream.GetBytes();
         File.WriteAllBytes(path, bytes);
     }
 }
 public void Notify(SignedLedger ledger)
 {
     foreach (var subscriptor in subscriptors)
     {
         foreach (var notification in GetNotifications(subscriptor.Value, ledger))
         {
             Send(subscriptor.Key, new NotificationMessage(notification));
         }
     }
 }
示例#10
0
        public void Initialize(SignedLedger lastLedger, bool needToSetInitial)
        {
            Injector.Inject(this);
            needSetInitialLedger = needToSetInitial;
            var validatorManager = LiveService.ValidatorManager;

            SignedLedgerValidator = new SignedLedgerValidator(validatorManager.GetValidators(), validatorManager.Quorum, Network);

            InitializeLedger(lastLedger);
        }
示例#11
0
        public void Notify(SignedLedger ledger)
        {
            foreach (var subscriptor in subscriptors)
            {
                if (!TryUpdateFunds())
                {
                    continue;
                }

                SendNotification(subscriptor, ledger.Ledger.LedgerLight.Height);
            }
        }
示例#12
0
        private void SetNextLedger(SignedLedger signed)
        {
            Debug.Assert(ValidateSignedLedgerInternal(signed));
            Debug.Assert(ValidateSignatures(signed));

            Finalize(signed, CreateLedgerState(signed));

            needSetInitialLedger = false;
            var time = TimeFormat.ToDateTime(signed.GetTimestamp());

            Console.WriteLine($"Ledger Finalized. Height : {signed.Ledger.LedgerLight.Height}  Timestamp : {time} Transactions : {signed.Ledger.Block.Transactions.Count()} ");
        }
        public static Internals.Ledger GetLedger(SignedLedger ledger)
        {
            if (ledger == null)
            {
                return(null);
            }

            var light        = ledger.Ledger.LedgerLight;
            var txs          = ledger.Ledger.Block.Transactions;
            var transactions = txs.Select(GetTransactionHeader).ToList();

            return(new Internals.Ledger(light.Height, ledger.Hash.ToBase64(), light.Timestamp, light.Lastledger.ToBase64(), light.Version.VersionNumber, ledger.Ledger.Block.FeeTransactionIndex, transactions));
        }
 public static bool TryReadSignedLedger(GetSignedLedgerResponse response, out SignedLedger signed)
 {
     try
     {
         signed = LedgerCompressionEngine.ReadZippedLedger(Convert.FromBase64String(response.Ledger));
     }
     catch
     {
         signed = null;
         return(false);
     }
     return(true);
 }
示例#15
0
 public void Notify(SignedLedger ledger)
 {
     foreach (var manager in managers)
     {
         try
         {
             manager.Notify(ledger);
         }
         catch (Exception e)
         {
             logger.Log("SubscriptionManager", e);
         }
     }
 }
        private SignedLedger CreateSignedLedger()
        {
            var account1 = PrivateKeyNotWallet.FromBase64("AKiWI3xivi2tsMz1Sh/v+0WrJaM60t/3h/qcEfu6r1pH");
            var block    = Block.CreateBlock(1, new List <SignedTransaction> {
                CreateSignedTransaction()
            });
            var merkle = new LedgerMerkleRoot(new List <Account>(), new List <TxDeclaration>(), new FakeLogger(), new Hasher()).Hash;
            var ledger = new Ledger(new LedgerLight(1, DateTime.UtcNow.ToUnixTimestamp(), new LedgerHash(Hash256.Zero.Bytes), new ProtocolVersion(0x1)), block, merkle);
            var signed = new SignedLedger(ledger);
            var hash   = signed.Hash;

            signed.AddSignature(account1.CreateSignature(hash, Network));
            return(signed);
        }
 public void Notify(SignedLedger ledger)
 {
     foreach (var subscriptor in subscriptors)
     {
         var notification = new LedgerNotification()
         {
             Hash         = ledger.Hash.ToBase64(),
             Height       = ledger.GetHeight(),
             Timestamp    = ledger.GetTimestamp(),
             Transactions = ledger.Ledger.Block.Transactions.Count()
         };
         Send(subscriptor, new NotificationMessage(notification));
     }
 }
示例#18
0
 public void Notify(SignedLedger ledger)
 {
     foreach (var subscriptor in subscriptors)
     {
         var notification = new ConfirmationNotification()
         {
             Hash         = ledger.Hash.ToBase64(),
             Height       = ledger.GetHeight(),
             Timestamp    = ledger.GetTimestamp(),
             Transactions = GetTransactions(subscriptor.Value, ledger)
         };
         Send(subscriptor.Key, new NotificationMessage(notification));
     }
 }
示例#19
0
        public bool ValidateSignedLedger(SignedLedger signed)
        {
            if (signed.Ledger.LedgerLight.Height != GetNextHeight())
            {
                return(false);
            }

            if (!signed.Ledger.LedgerLight.Lastledger.Equals(GetLastLedgerHash()))
            {
                return(false);
            }

            return(true);
        }
        public void ProcessNewLedger(SignedLedger ledger)
        {
            var accountsToUpdate = GetChangedAccounts(ledger);

            var changes = UpdateOrderbook(accountsToUpdate);

            foreach (var change in changes)
            {
                if (change.Value)
                {
                    TryGetOrderBook(change.Key, out var orderbook);
                    OrderBookUpdated(change.Key, orderbook);
                }
            }
        }
示例#21
0
        // we finalize the ledger and create a new immutable ledger state
        private void Finalize(SignedLedger signed, LedgerPostState state)
        {
            var ledgerState = state.Finalize(HasherFactory.CreateHasher(signed.GetVersion()));

            if (!CheckMerkleRoot(ledgerState, signed))
            {
                throw new Exception("Merkle root is not valid");
            }

            LiveService.PersistenceManager.Save(new SignedLedgerState(signed, state.GetLedgerStateChange()));

            LedgerState = ledgerState;
            LastLedger  = signed;

            OnNewLedger(LastLedger);
        }
示例#22
0
        public bool ValidateSignatures(SignedLedger signedLedger)
        {
            // TODO check that fee transaction = total fees

            // TODO is this correct?
            var status = SignedLedgerValidator.Validate(signedLedger);

            if (status == LedgerValidationStatus.Ok)
            {
                return(true);
            }

            logger.Log($"LedgerManager : SignedLedger signature validation Failed! {status}");

            return(false);
        }
 public static bool TryReadSignedLedger(GetSignedLedgerResponse response, out SignedLedger signed)
 {
     try
     {
         using (var stream = new ByteStream(Convert.FromBase64String(response.Ledger)))
         {
             signed = stream.ReadSignedLedger();
         }
     }
     catch
     {
         signed = null;
         return(false);
     }
     return(true);
 }
        private TransactionDeclarationContext CreateDeclarationContext(SignedLedger signed, List <TransactionDeclarationEntity> declarations)
        {
            var context = new TransactionDeclarationContext();

            foreach (var transaction in signed.Ledger.Block.Transactions)
            {
                var index = 0;
                foreach (var declaration in transaction.Transaction.Declarations)
                {
                    if (!MatchInContext(context, declarations, declaration, transaction.Hash, index++))
                    {
                        throw new NotImplementedException("It should match");
                    }
                }
            }
            return(context);
        }
示例#25
0
        // we create a new ledger state based on the current state and the new ledger
        private LedgerPostState CreateLedgerState(SignedLedger signedLedger)
        {
            var state = new LedgerPostState(LedgerState, signedLedger.GetHeight())
            {
                AccountCreated = account => LiveService.AccountManager.AddAccount(account.Address, new ExtendedAccount(account))
            };

            byte index = 0;

            foreach (var signed in signedLedger.Ledger.Block.Transactions)
            {
                // TODO make a better validation
                // Debug.Assert(signed.Transaction.Expire > signedLedger.Ledger.LedgerLight.BeginTime);
                Debug.Assert(signedLedger.Ledger.Block.FeeTransactionIndex == index++ || LiveService.TransactionManager.TransactionValidator.ValidateBalance(state, signed.Transaction.GetInputs()));
                LedgerService.SignedTransactionManager.Execute(state, signed.Transaction);
            }

            return(state);
        }
        private Dictionary <Address, Account> GetChangedAccounts(SignedLedger ledger)
        {
            var accountsToUpdate = new Dictionary <Address, Account>();

            foreach (var transaction in ledger.Ledger.Block.Transactions)
            {
                foreach (var input in transaction.Transaction.Inputs)
                {
                    if (accountsToUpdate.ContainsKey(input.Address))
                    {
                        continue;
                    }

                    if (LedgerService.LedgerManager.LedgerState.TryGetAccount(input.Address, out var account))
                    {
                        if (account.Address.Type == AddressType.VendingMachine)
                        {
                            accountsToUpdate.Add(account.Address, account);
                        }
                    }
                }

                foreach (var input in transaction.Transaction.Outputs)
                {
                    if (accountsToUpdate.ContainsKey(input.Address))
                    {
                        continue;
                    }

                    if (LedgerService.LedgerManager.LedgerState.TryGetAccount(input.Address, out var account))
                    {
                        if (account.Address.Type == AddressType.VendingMachine)
                        {
                            accountsToUpdate.Add(account.Address, account);
                        }
                    }
                }
            }

            return(accountsToUpdate);
        }
示例#27
0
        private void InitializeLedger(SignedLedger lastLedger)
        {
            var accounts = new Trie <Account>(Address.RAW_SIZE);

            foreach (var account in LiveService.AccountManager.GetAccounts())
            {
                accounts.CreateOrUpdate(account.Key.ToRawBytes(), old =>
                {
                    if (old != null)
                    {
                        throw new Exception("The ledger's account states are duplicated !");
                    }
                    return(account.Value);
                });
            }
            // TODO compute hash
            accounts.ComputeHash(HasherFactory.CreateHasher(lastLedger.GetVersion()));

            LedgerState = new LedgerStateFinal(accounts);
            LastLedger  = lastLedger;
            // Debug.Assert(SignedLedgerValidator.Validate(this.lastLedger) == LedgerValidationStatus.Ok, "Last Ledger is not valid"); // Most likely not enough signatures (see quorum)
        }
示例#28
0
        internal void OnLedgerUpdated(SignedLedger signed)
        {
            Console.WriteLine($"Ledger Updated ! Height {signed.Ledger.LedgerLight.Height}");
            foreach (var transaction in signed.Ledger.Block.Transactions)
            {
                foreach (var input in transaction.Transaction.Inputs)
                {
                    if (addresses.ContainsKey(input.Address.Encoded))
                    {
                        WalletUpdated.Call(input);
                    }
                }

                foreach (var output in transaction.Transaction.Outputs)
                {
                    if (addresses.ContainsKey(output.Address.Encoded))
                    {
                        WalletUpdated.Call(output);
                    }
                }
            }
        }
示例#29
0
        public static LedgerValidationStatus CheckSignatures(this SignedLedger ledger, LedgerRequiredValidatorsFactory factory, Network network)
        {
            var hash = ledger.Hash;
            // get required signatures
            var required = factory.GetRequiredValidators();

            // verify signatures
            foreach (var signature in ledger.Signatures)
            {
                if (!signature.PublicKey.Verify(hash, signature.SignatureByte, network))
                {
                    return(LedgerValidationStatus.InvalidPublicKey);
                }

                required.OnValidSignature(signature.PublicKey);
            }

            // check required signatures are set
            if (!required.IsValid())
            {
                return(LedgerValidationStatus.NotEnoughSignatures);
            }
            return(LedgerValidationStatus.Ok);
        }
示例#30
0
 private List <JSON.API.Internals.Transaction> GetTransactions(SessionSubscriptor subscriptor, SignedLedger ledger)
 {
     return(ledger.Ledger.Block.Transactions
            .Where(transaction => subscriptor.IsSubscribed(transaction, true))
            .Select(signed => TransactionConverter.GetTransaction(signed.Transaction)).ToList());
 }