예제 #1
0
        public void WriteParentChainBlockInfo(ParentChainBlockInfo parentChainBlockInfo)
        {
            ulong parentChainHeight = parentChainBlockInfo.Height;
            var   currentHeight     = _currentParentChainHeight.GetValue();
            var   target            = currentHeight != 0 ? currentHeight + 1: GlobalConfig.GenesisBlockHeight;

            Api.Assert(target == parentChainHeight,
                       $"Parent chain block info at height {target} is needed, not {parentChainHeight}");
            Console.WriteLine("ParentChainBlockInfo.Height is correct.");

            var key = new UInt64Value {
                Value = parentChainHeight
            };

            Api.Assert(_parentChainBlockInfo.GetValue(key) == null,
                       $"Already written parent chain block info at height {parentChainHeight}");
            Console.WriteLine("Writing ParentChainBlockInfo..");
            foreach (var _ in parentChainBlockInfo.IndexedBlockInfo)
            {
                BindParentChainHeight(_.Key, parentChainHeight);
                AddIndexedTxRootMerklePathInParentChain(_.Key, _.Value);
            }
            _parentChainBlockInfo.SetValueAsync(key, parentChainBlockInfo).Wait();
            _currentParentChainHeight.SetValue(parentChainHeight);

            // only for debug
            Console.WriteLine($"WriteParentChainBlockInfo success at {parentChainHeight}");
        }
예제 #2
0
        public void Deserialize()
        {
            var pcb = new ParentChainBlockInfo
            {
                Root = new ParentChainBlockRootInfo
                {
                    ChainId = Hash.Generate(),
                    Height  = 1,
                    SideChainBlockHeadersRoot = Hash.Default,
                    SideChainTransactionsRoot = Hash.Default
                }
            };

            var bytes = ByteString.CopyFrom(ParamsPacker.Pack(pcb));


            /*var aa = new SInt32Value
             * {
             *  Value = 202
             * };
             * string ass = ByteString.CopyFrom(aa.ToByteArray()).ToByteArray().ToHex();
             * System.Diagnostics.Debug.WriteLine(ass);
             * var data = ByteArrayHelpers.FromHexString(ass);*/
            System.Diagnostics.Debug.WriteLine((ParentChainBlockInfo)(ParamsPacker.Unpack(bytes.ToByteArray(), new[] { typeof(ParentChainBlockInfo) })[0]));
        }
예제 #3
0
        public async Task MerklePathTest()
        {
            Init();
            var chainId = Mock.ChainId1;

            _contract = new SideChainContractShim(Mock, AddressHelpers.GetSystemContractAddress(chainId, SmartContractType.SideChainContract.ToString()));
            ulong pHeight = 1;
            ParentChainBlockRootInfo parentChainBlockRootInfo = new ParentChainBlockRootInfo
            {
                ChainId = chainId,
                Height  = pHeight,
                SideChainTransactionsRoot = Hash.Generate(),
                SideChainBlockHeadersRoot = Hash.Generate()
            };
            ParentChainBlockInfo parentChainBlockInfo = new ParentChainBlockInfo
            {
                Root = parentChainBlockRootInfo
            };

            parentChainBlockInfo.IndexedBlockInfo.Add(0, new MerklePath
            {
                Path = { Hash.FromString("Block1"), Hash.FromString("Block2"), Hash.FromString("Block3") }
            });
            await _contract.WriteParentChainBLockInfo(parentChainBlockInfo);

            ChainConfig.Instance.ChainId = chainId.DumpHex();
            var crossChainInfo = new CrossChainInfo(Mock.StateStore);
            var merklepath     = crossChainInfo.GetTxRootMerklePathInParentChain(0);

            Assert.NotNull(merklepath);
            Assert.Equal(parentChainBlockInfo.IndexedBlockInfo[0], merklepath);

            var parentHeight = crossChainInfo.GetParentChainCurrentHeight();

            Assert.Equal(pHeight, parentHeight);
            var boundHeight = crossChainInfo.GetBoundParentChainHeight(0);

            Assert.Equal(parentChainBlockRootInfo.Height, boundHeight);

            var boundBlockInfo = crossChainInfo.GetBoundParentChainBlockInfo(parentChainBlockRootInfo.Height);

            Assert.Equal(parentChainBlockInfo, boundBlockInfo);
        }
예제 #4
0
파일: BlockExecutor.cs 프로젝트: shiwk/AElf
 /// <summary>
 /// Validate parent chain block info.
 /// </summary>
 /// <returns>
 /// Return false if validation failed and then that block execution would fail.
 /// </returns>
 private bool ValidateParentChainBlockInfoTransaction(ParentChainBlockInfo parentBlockInfo)
 {
     try
     {
         var cached = _clientManager.TryGetParentChainBlockInfo(parentBlockInfo);
         if (cached != null)
         {
             return(cached.Equals(parentBlockInfo));
         }
         //_logger.Warn("Not found cached parent block info");
         return(false);
     }
     catch (Exception e)
     {
         if (e is ClientShutDownException)
         {
             return(true);
         }
         _logger.Warn("Parent chain block info validation failed.");
         return(false);
     }
 }
예제 #5
0
        /// <summary>
        /// Try to take first one in cached queue
        /// </summary>
        /// <param name="pcb"> Mining processing if it is null, synchronization processing otherwise.</param>
        /// <returns>
        /// return the first one cached by <see cref="ClientToParentChain"/>
        /// </returns>
        public ParentChainBlockInfo TryGetParentChainBlockInfo(ParentChainBlockInfo pcb = null)
        {
            if (!GrpcLocalConfig.Instance.ClientToParentChain)
            {
                throw new ClientShutDownException("Client to parent chain is shut down");
            }
            if (_clientToParentChain == null)
            {
                return(null);
            }
            var chainId = GrpcRemoteConfig.Instance.ParentChain?.ElementAtOrDefault(0).Key;

            if (chainId == null)
            {
                return(null);
            }
            Hash  parentChainId = Hash.LoadHex(chainId);
            ulong targetHeight  = GetParentChainTargetHeight();

            // _logger?.Trace($"To get pcb at height {targetHeight}");
            if (pcb != null && !(pcb.ChainId.Equals(parentChainId) && targetHeight == pcb.Height))
            {
                return(null);
            }

            if (!_clientToParentChain.TryTake(WaitingIntervalInMillisecond, targetHeight, out var blockInfo, pcb == null))
            {
                return(null);
            }

            if (pcb == null || pcb.Equals(blockInfo))
            {
                return((ParentChainBlockInfo)blockInfo);
            }

            _logger.Trace($"Cached parent block info is {blockInfo}");
            _logger.Trace($"Parent block info in transaction is {pcb}");
            return(null);
        }
예제 #6
0
        public async Task VerifyTransactionTest()
        {
            Init();
            var chainId = Mock.ChainId1;

            ChainConfig.Instance.ChainId = chainId.DumpHex();
            _contract = new SideChainContractShim(Mock, AddressHelpers.GetSystemContractAddress(chainId, SmartContractType.SideChainContract.ToString()));
            ulong pHeight = 1;
            ParentChainBlockRootInfo pcbr1 = new ParentChainBlockRootInfo
            {
                ChainId = chainId,
                Height  = pHeight,
                SideChainTransactionsRoot = Hash.Generate(),
                SideChainBlockHeadersRoot = Hash.Generate()
            };
            ParentChainBlockInfo pcb1 = new ParentChainBlockInfo
            {
                Root = pcbr1
            };

            pcb1.IndexedBlockInfo.Add(0, new MerklePath
            {
                Path = { Hash.FromString("Block1"), Hash.FromString("Block2"), Hash.FromString("Block3") }
            });
            await _contract.WriteParentChainBLockInfo(pcb1);

            var crossChainInfo = new CrossChainInfo(Mock.StateStore);
            var parentHeight   = crossChainInfo.GetParentChainCurrentHeight();

            Assert.Equal(pHeight, parentHeight);

            Transaction t1 = new Transaction
            {
                From       = Address.FromString("1"),
                To         = Address.FromString("2"),
                MethodName = "test",
                Sig        = new Signature
                {
                    P = ByteString.Empty,
                    R = ByteString.Empty,
                },
                Params         = ByteString.Empty,
                RefBlockNumber = 0,
                RefBlockPrefix = ByteString.Empty
            };
            var hashCount = 10;

            var list1 = new List <Hash> {
                t1.GetHash()
            };

            for (int i = 0; i < hashCount; i++)
            {
                list1.Add(Hash.Generate());
            }

            var bmt1 = new BinaryMerkleTree();

            bmt1.AddNodes(list1);
            var root1        = bmt1.ComputeRootHash();
            var sc1BlockInfo = new SideChainBlockInfo
            {
                Height            = pHeight,
                BlockHeaderHash   = Hash.Generate(),
                ChainId           = Hash.Generate(),
                TransactionMKRoot = root1
            };

            Transaction t2 = new Transaction
            {
                From       = Address.FromString("3"),
                To         = Address.FromString("4"),
                MethodName = "test",
                Sig        = new Signature
                {
                    P = ByteString.Empty,
                    R = ByteString.Empty,
                },
                Params         = ByteString.Empty,
                RefBlockNumber = 1,
                RefBlockPrefix = ByteString.Empty
            };
            var list2 = new List <Hash> {
                t2.GetHash(), Hash.FromString("d"), Hash.FromString("e"), Hash.FromString("f"), Hash.FromString("a"), Hash.FromString("b"), Hash.FromString("c")
            };
            var bmt2 = new BinaryMerkleTree();

            bmt2.AddNodes(list2);
            var root2        = bmt2.ComputeRootHash();
            var sc2BlockInfo = new SideChainBlockInfo
            {
                Height            = pHeight,
                BlockHeaderHash   = Hash.Generate(),
                ChainId           = Hash.Generate(),
                TransactionMKRoot = root2
            };

            var block = new Block
            {
                Header = new BlockHeader(),
                Body   = new BlockBody()
            };

            block.Body.IndexedInfo.Add(new List <SideChainBlockInfo> {
                sc1BlockInfo, sc2BlockInfo
            });
            block.Body.CalculateMerkleTreeRoots();

            pHeight = 2;
            ParentChainBlockRootInfo parentChainBlockRootInfo = new ParentChainBlockRootInfo
            {
                ChainId = chainId,
                Height  = pHeight,
                SideChainTransactionsRoot = block.Body.SideChainTransactionsRoot,
                SideChainBlockHeadersRoot = Hash.FromString("SideChainBlockHeadersRoot")
            };

            ParentChainBlockInfo parentChainBlockInfo = new ParentChainBlockInfo
            {
                Root = parentChainBlockRootInfo
            };
            var tree       = block.Body.BinaryMerkleTreeForSideChainTransactionRoots;
            var pathForTx1 = bmt1.GenerateMerklePath(0);

            Assert.Equal(root1, pathForTx1.ComputeRootWith(t1.GetHash()));
            var pathForSc1Block = tree.GenerateMerklePath(0);

            pathForTx1.Path.AddRange(pathForSc1Block.Path);

            var pathForTx2      = bmt2.GenerateMerklePath(0);
            var pathForSc2Block = tree.GenerateMerklePath(1);

            pathForTx2.Path.AddRange(pathForSc2Block.Path);

            //parentChainBlockInfo.IndexedBlockInfo.Add(1, tree.GenerateMerklePath(0));
            await _contract.WriteParentChainBLockInfo(parentChainBlockInfo);

            //crossChainInfo = new CrossChainInfo(Mock.StateStore);
            parentHeight = crossChainInfo.GetParentChainCurrentHeight();
            Assert.Equal(pHeight, parentHeight);

            var b = await _contract.VerifyTransaction(t1.GetHash(), pathForTx1, parentChainBlockRootInfo.Height);

            Assert.True(b);

            b = await _contract.VerifyTransaction(t2.GetHash(), pathForTx2, parentChainBlockRootInfo.Height);

            Assert.True(b);
        }
예제 #7
0
파일: Miner.cs 프로젝트: wyk125/AElf
        /// <summary>
        /// Get <see cref="ParentChainBlockInfo"/> from executed transaction
        /// </summary>
        /// <param name="sysTxns">Executed transactions.</param>
        /// <param name="traces"></param>
        /// <param name="parentChainBlockInfo"></param>
        private void FindCrossChainInfo(List <Transaction> sysTxns, List <TransactionTrace> traces, out ParentChainBlockInfo parentChainBlockInfo)
        {
            parentChainBlockInfo = null;
            var crossChainTx =
                sysTxns.FirstOrDefault(t => t.Type == TransactionType.CrossChainBlockInfoTransaction);

            if (crossChainTx == null)
            {
                return;
            }

            var trace = traces.FirstOrDefault(t => t.TransactionId.Equals(crossChainTx.GetHash()));

            if (trace == null || trace.ExecutionStatus != ExecutionStatus.ExecutedAndCommitted)
            {
                return;
            }
            parentChainBlockInfo = (ParentChainBlockInfo)ParamsPacker.Unpack(crossChainTx.Params.ToByteArray(),
                                                                             new[] { typeof(ParentChainBlockInfo) })[0];
        }