예제 #1
0
        /// <summary>
        /// Compare
        /// </summary>
        /// <param name="block"></param>
        /// <returns></returns>
        public async Task <bool> ValidateBlockAfterExecuteAsync(IBlock block)
        {
            if (block.Header.Height == AElfConstants.GenesisBlockHeight)
            {
                return(true);
            }

            var tokenContractAddress =
                await _smartContractAddressService.GetAddressByContractNameAsync(new ChainContext
            {
                BlockHash   = block.GetHash(),
                BlockHeight = block.Header.Height
            }, TokenSmartContractAddressNameProvider.StringName);

            if (tokenContractAddress == null)
            {
                return(true);
            }

            var hashFromState = await _contractReaderFactory.Create(new ContractReaderContext
            {
                BlockHash       = block.GetHash(),
                BlockHeight     = block.Header.Height,
                ContractAddress = tokenContractAddress
            }).GetLatestTotalResourceTokensMapsHash.CallAsync(new Empty());

            var totalResourceTokensMapsFromProvider =
                await _totalResourceTokensMapsProvider.GetTotalResourceTokensMapsAsync(new ChainContext
            {
                BlockHash   = block.Header.PreviousBlockHash,
                BlockHeight = block.Header.Height - 1
            });

            if (hashFromState.Value.IsEmpty)
            {
                // If hash from state is empty, data from provider must be null.
                return(totalResourceTokensMapsFromProvider == null);
            }

            if (hashFromState == HashHelper.ComputeFrom(new TotalResourceTokensMaps
            {
                BlockHash = block.Header.PreviousBlockHash,
                BlockHeight = block.Header.Height - 1
            }))
            {
                if (totalResourceTokensMapsFromProvider == null)
                {
                    return(true);
                }
                return(totalResourceTokensMapsFromProvider.BlockHeight != block.Header.Height - 1);
            }

            if (totalResourceTokensMapsFromProvider == null)
            {
                return(false);
            }
            var hashFromProvider = HashHelper.ComputeFrom(totalResourceTokensMapsFromProvider);

            return(hashFromState == hashFromProvider);
        }
        /// <summary>
        /// Compare 
        /// </summary>
        /// <param name="block"></param>
        /// <returns></returns>
        public async Task<bool> ValidateBlockAfterExecuteAsync(IBlock block)
        {
            var tokenContractAddress =
                _smartContractAddressService.GetAddressByContractName(TokenSmartContractAddressNameProvider.Name);
            if (tokenContractAddress == null)
            {
                return true;
            }

            var hashFromState = await _tokenReaderFactory.Create(block.GetHash(), block.Header.Height)
                .GetLatestTotalResourceTokensMapsHash.CallAsync(new Empty());
            var totalResourceTokensMapsFromProvider =
                await _totalResourceTokensMapsProvider.GetTotalResourceTokensMapsAsync(new ChainContext
                {
                    BlockHash = block.GetHash(),
                    BlockHeight = block.Header.Height
                });
            if (totalResourceTokensMapsFromProvider == null)
            {
                Logger.LogInformation("totalResourceTokensMapsFromProvider == null");
                return hashFromState.Value.IsEmpty || hashFromState ==
                       Hash.FromMessage(TotalResourceTokensMaps.Parser.ParseFrom(ByteString.Empty));
            }

            var hashFromProvider = Hash.FromMessage(totalResourceTokensMapsFromProvider);
            var result = hashFromProvider.Value.Equals(hashFromState.Value);
            if (!result)
            {
                Logger.LogError($"Hash from provider: {hashFromProvider}\nHash from state: {hashFromState}");
            }

            return result;
        }
예제 #3
0
        public async Task <List <Transaction> > GenerateTransactionsAsync(Address @from, long preBlockHeight,
                                                                          Hash preBlockHash)
        {
            var generatedTransactions = new List <Transaction>();

            var chainContext = new ChainContext
            {
                BlockHash   = preBlockHash,
                BlockHeight = preBlockHeight
            };

            var tokenContractAddress =
                await _smartContractAddressService.GetAddressByContractNameAsync(chainContext,
                                                                                 TokenSmartContractAddressNameProvider.StringName);

            if (tokenContractAddress == null)
            {
                return(generatedTransactions);
            }

            var totalResourceTokensMaps = await _totalResourceTokensMapsProvider.GetTotalResourceTokensMapsAsync(
                chainContext);

            ByteString input;

            if (totalResourceTokensMaps != null && totalResourceTokensMaps.BlockHeight == preBlockHeight &&
                totalResourceTokensMaps.BlockHash == preBlockHash)
            {
                // If totalResourceTokensMaps match current block.
                input = totalResourceTokensMaps.ToByteString();
            }
            else
            {
                input = new TotalResourceTokensMaps
                {
                    BlockHash   = preBlockHash,
                    BlockHeight = preBlockHeight
                }.ToByteString();
            }

            generatedTransactions.AddRange(new List <Transaction>
            {
                new Transaction
                {
                    From           = from,
                    MethodName     = nameof(TokenContractImplContainer.TokenContractImplStub.DonateResourceToken),
                    To             = tokenContractAddress,
                    RefBlockNumber = preBlockHeight,
                    RefBlockPrefix = BlockHelper.GetRefBlockPrefix(preBlockHash),
                    Params         = input
                }
            });

            Logger.LogTrace("Tx DonateResourceToken generated.");
            return(generatedTransactions);
        }
예제 #4
0
        public async Task ProcessAsync(Block block, TransactionResult transactionResult, LogEvent logEvent)
        {
            var eventData = new ResourceTokenCharged();

            eventData.MergeFrom(logEvent);
            if (eventData.Symbol == null || eventData.Amount == 0)
            {
                return;
            }

            var blockHash   = block.GetHash();
            var blockHeight = block.Height;
            // TODO: Get -> Modify -> Set is slow, consider collect all logEvents then generate the totalResourceTokensMap at once.
            var totalResourceTokensMaps =
                await _totalTotalResourceTokensMapsProvider.GetTotalResourceTokensMapsAsync(
                    new ChainContext
            {
                BlockHash   = block.GetHash(),
                BlockHeight = block.Height,
            });

            // Initial totalTxFeesMap if necessary (either never initialized or not initialized for current block link)
            if (totalResourceTokensMaps == null)
            {
                totalResourceTokensMaps = new TotalResourceTokensMaps
                {
                    BlockHash   = blockHash,
                    BlockHeight = blockHeight
                };
            }
            else if (totalResourceTokensMaps.BlockHash != blockHash || totalResourceTokensMaps.BlockHeight != blockHeight)
            {
                totalResourceTokensMaps = new TotalResourceTokensMaps
                {
                    BlockHash   = blockHash,
                    BlockHeight = blockHeight
                };
            }

            if (totalResourceTokensMaps.Value.Any() &&
                totalResourceTokensMaps.Value.Any(b => b.ContractAddress == eventData.ContractAddress))
            {
                var oldBill = totalResourceTokensMaps.Value.First(b => b.ContractAddress == eventData.ContractAddress);
                if (oldBill.TokensMap.Value.ContainsKey(eventData.Symbol))
                {
                    oldBill.TokensMap.Value[eventData.Symbol] += eventData.Amount;
                }
                else
                {
                    oldBill.TokensMap.Value.Add(eventData.Symbol, eventData.Amount);
                }
            }
            else
            {
                var contractTotalResourceTokens = new ContractTotalResourceTokens
                {
                    ContractAddress = eventData.ContractAddress,
                    TokensMap       = new TotalResourceTokensMap
                    {
                        Value =
                        {
                            { eventData.Symbol, eventData.Amount }
                        }
                    }
                };
                totalResourceTokensMaps.Value.Add(contractTotalResourceTokens);
            }

            await _totalTotalResourceTokensMapsProvider.SetTotalResourceTokensMapsAsync(new BlockIndex
            {
                BlockHash   = blockHash,
                BlockHeight = blockHeight
            }, totalResourceTokensMaps);
        }
        public async Task <List <Transaction> > GenerateTransactionsAsync(Address @from, long preBlockHeight,
                                                                          Hash preBlockHash)
        {
            var generatedTransactions = new List <Transaction>();

            if (preBlockHeight == 1)
            {
                return(generatedTransactions);
            }

            if (preBlockHeight < AElfConstants.GenesisBlockHeight)
            {
                return(generatedTransactions);
            }

            var tokenContractAddress = _smartContractAddressService.GetAddressByContractName(
                TokenSmartContractAddressNameProvider.Name);

            if (tokenContractAddress == null)
            {
                return(generatedTransactions);
            }

            var chainContext = new ChainContext
            {
                BlockHash   = preBlockHash,
                BlockHeight = preBlockHeight
            };
            var totalResourceTokensMaps = await _totalResourceTokensMapsProvider.GetTotalResourceTokensMapsAsync(
                chainContext);

            var input = ByteString.Empty;

            if (totalResourceTokensMaps != null && totalResourceTokensMaps.BlockHeight == preBlockHeight &&
                totalResourceTokensMaps.BlockHash == preBlockHash)
            {
                input = totalResourceTokensMaps.ToByteString();
            }
            else
            {
                await _totalResourceTokensMapsProvider.SetTotalResourceTokensMapsAsync(new BlockIndex
                {
                    BlockHash   = preBlockHash,
                    BlockHeight = preBlockHeight
                }, TotalResourceTokensMaps.Parser.ParseFrom(ByteString.Empty));
            }

            generatedTransactions.AddRange(new List <Transaction>
            {
                new Transaction
                {
                    From           = from,
                    MethodName     = nameof(TokenContractImplContainer.TokenContractImplStub.DonateResourceToken),
                    To             = tokenContractAddress,
                    RefBlockNumber = preBlockHeight,
                    RefBlockPrefix = ByteString.CopyFrom(preBlockHash.Value.Take(4).ToArray()),
                    Params         = input
                }
            });

            Logger.LogInformation("Tx DonateResourceToken generated.");
            return(generatedTransactions);
        }