Skip to content

Commit

Permalink
feat: Add hold token event for the EVM action - MEED-6663 - Meeds-io/…
Browse files Browse the repository at this point in the history
…MIPs#118 (#66)

This change will add the hold token event for the EVM action.
  • Loading branch information
MayTekayaa authored Nov 12, 2024
1 parent dc45891 commit 4acff9f
Show file tree
Hide file tree
Showing 15 changed files with 302 additions and 254 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,28 @@

import io.meeds.evm.gamification.entity.EvmTransactionEntity;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;

import java.util.List;

public interface EvmTransactionDAO extends JpaRepository<EvmTransactionEntity, Long> {

List<EvmTransactionEntity> findByFromAddress(String fromAddress);
@Query("""
SELECT DISTINCT fromAddress AS address FROM EvmTransaction tr
WHERE tr.contractAddress = ?1 AND tr.transactionDate >= ?2
UNION
SELECT DISTINCT toAddress AS address FROM EvmTransaction tr
WHERE tr.contractAddress = ?1 AND tr.transactionDate >= ?2
""")
List<String> findDistinctAddresses(String contractAddress, Long ruleCreationDate);

List<EvmTransactionEntity> findByContractAddressAndNetworkIdAndIdGreaterThan(String contractAddress, Long networkId, Long id);

EvmTransactionEntity findTopByContractAddressAndNetworkIdOrderByIdDesc(String contractAddress, Long networkId);
List<EvmTransactionEntity> findByContractAddressAndNetworkIdAndToAddressAndTransactionDateGreaterThan(String contractAddress,
Long networkId,
String toAddress,
Long transactionDate);

List<EvmTransactionEntity> findByContractAddressAndNetworkIdAndFromAddressAndTransactionDateGreaterThan(String contractAddress,
Long networkId,
String fromAddress,
Long transactionDate);
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,26 +33,35 @@ public class EvmTransactionEntity implements Serializable {
@SequenceGenerator(name = "SEQ_EVM_TRANSACTIONS_ID", sequenceName = "SEQ_EVM_TRANSACTIONS_ID", allocationSize = 1)
@GeneratedValue(strategy = GenerationType.AUTO, generator = "SEQ_EVM_TRANSACTIONS_ID")
@Column(name = "ID", nullable = false)
private Long id;
private Long id;

@Column(name = "TRANSACTION_HASH", nullable = false)
private String transactionHash;
private String transactionHash;

@Column(name = "NETWORK_ID", nullable = false)
private Long networkId;
private Long networkId;

@Column(name = "FROM_ADDRESS", nullable = false)
private String fromAddress;
private String fromAddress;

@Column(name = "TO_ADDRESS", nullable = false)
private String toAddress;
private String toAddress;

@Column(name = "CONTRACT_ADDRESS", nullable = false)
private String contractAddress;
private String contractAddress;

@Column(name = "SENT_DATE", nullable = false)
private Long sentDate;
@Column(name = "TRANSACTION_DATE", nullable = false)
private Long transactionDate;

@Column(name = "AMOUNT", nullable = false)
private BigInteger amount;
private BigInteger amount;

@Column(name = "WALLET_BALANCE", nullable = false)
private BigInteger walletBalance;

@Column(name = "BLOCK_NUMBER", nullable = false)
private BigInteger blockNumber;

@Column(name = "BLOCK_HASH", nullable = false)
private String blockHash;
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,14 @@ public class EvmTransaction {

private String contractAddress;

private Long sentDate;
private Long transactionDate;

private BigInteger amount;

private BigInteger walletBalance;

private BigInteger blockNumber;

private String blockHash;

}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@
import org.springframework.stereotype.Component;

@Component
public class EvmContractTransferTask {
private static final Logger LOG = LoggerFactory.getLogger(EvmContractTransferTask.class);
public class EvmContractSaveTask {
private static final Logger LOG = LoggerFactory.getLogger(EvmContractSaveTask.class);

private static final Scope SETTING_SCOPE = Scope.APPLICATION.id("GAMIFICATION_EVM");

Expand All @@ -55,28 +55,13 @@ public class EvmContractTransferTask {
private EvmContractTransferService evmContractTransferService;

@ContainerTransactional
@Scheduled(cron = "0 * * * * *")
public synchronized void listenEVMContractTransfer() {
try {
List<RuleDTO> filteredRules = evmContractTransferService.getFilteredEVMRules();
if (CollectionUtils.isNotEmpty(filteredRules)) {
filteredRules.forEach(rule -> {
evmContractTransferService.listenEvmContractTransfer(rule);
});
}
} catch (Exception e) {
LOG.error("An error occurred while rewarding for EVM events", e);
}
}

@ContainerTransactional
@Scheduled(cron = "0 * * * * *")
@Scheduled(cron = "${gamification.evm.transactionSave.cron:0 */15 * * * *}")
public synchronized void saveEVMContractTransactions() {
try {
List<RuleDTO> filteredRules = evmContractTransferService.getFilteredEVMRules();
if (CollectionUtils.isNotEmpty(filteredRules)) {
LOG.info("Start listening evm token transfers for {} configured rules", filteredRules.size());
filteredRules.forEach(rule -> {
List<RuleDTO> rules = evmContractTransferService.getEvmRules();
if (CollectionUtils.isNotEmpty(rules)) {
LOG.info("Start listening evm token transfers for {} configured rules", rules.size());
rules.forEach(rule -> {
String blockchainNetwork = rule.getEvent().getProperties().get(Utils.BLOCKCHAIN_NETWORK);
String contractAddress = rule.getEvent().getProperties().get(Utils.CONTRACT_ADDRESS);
String networkId = rule.getEvent().getProperties().get(Utils.NETWORK_ID);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* This file is part of the Meeds project (https://meeds.io/).
* Copyright (C) 2020 - 2024 Meeds Association [email protected]
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package io.meeds.evm.gamification.scheduling.task;

import java.util.List;

import io.meeds.common.ContainerTransactional;
import io.meeds.evm.gamification.service.EvmContractTransferService;
import io.meeds.gamification.model.RuleDTO;

import org.apache.commons.collections4.CollectionUtils;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

@Component
public class EvmContractScanTask {
private static final Logger LOG = LoggerFactory.getLogger(EvmContractSaveTask.class);

@Autowired
private EvmContractTransferService evmContractTransferService;

@ContainerTransactional
@Scheduled(cron = "${gamification.evm.transactionScan.cron:0 */2 * * * *}")
public synchronized void scanForContractTransactions() {

List<RuleDTO> enabledRules = evmContractTransferService.getEnabledEvmRules();
if (CollectionUtils.isNotEmpty(enabledRules)) {
enabledRules.forEach(rule -> {
try {
evmContractTransferService.scanForContractTransactions(rule);
} catch (Exception e) {
LOG.error("An error occurred while rewarding for {} rule", rule.getTitle(), e);
}
});
}

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;

import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
import org.exoplatform.wallet.contract.ERC20;
import org.exoplatform.wallet.contract.ERC20.TransferEventResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.web3j.abi.EventEncoder;
Expand All @@ -44,11 +50,6 @@
import org.web3j.tx.ReadonlyTransactionManager;
import org.web3j.tx.gas.StaticGasProvider;

import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
import org.exoplatform.wallet.contract.ERC20;
import org.exoplatform.wallet.contract.ERC20.TransferEventResponse;

import io.meeds.evm.gamification.blockchain.BlockchainConfiguration;
import io.meeds.evm.gamification.model.EvmContract;
import io.meeds.evm.gamification.model.EvmTransaction;
Expand Down Expand Up @@ -107,7 +108,7 @@ public void saveTokenTransactions(long fromBlock,
.map(EthLog.LogObject::getTransactionHash)
.map(transactionHash -> getTransactionReceipt(transactionHash, networkWeb3j))
.filter(TransactionReceipt::isStatusOK)
.flatMap(transactionReceipt -> getTransferEvents(transactionReceipt, contractAddress))
.flatMap(transactionReceipt -> getTransferEvents(transactionReceipt, contractAddress, blockchainNetwork))
.toList();
if (transferEvents != null && !transferEvents.isEmpty()) {
transferEvents.forEach(transferEvent -> {
Expand All @@ -117,7 +118,7 @@ public void saveTokenTransactions(long fromBlock,
|| (receiver != null && StringUtils.isNotBlank(receiver.getAddress()))) {
transferEvent.setContractAddress(contractAddress);
transferEvent.setNetworkId(networkId);
transferEvent.setSentDate(System.currentTimeMillis());
transferEvent.setTransactionDate(System.currentTimeMillis());
evmTransactionService.saveTransaction(transferEvent);
}
});
Expand Down Expand Up @@ -218,16 +219,19 @@ private ERC20 loadERC20Token(String contractAddress, Web3j networkWeb3j) {
new StaticGasProvider(BigInteger.valueOf(20000000000l), BigInteger.valueOf(300000l)));
}

private Stream<EvmTransaction> getTransferEvents(TransactionReceipt transactionReceipt, String contractAddress) {
private Stream<EvmTransaction> getTransferEvents(TransactionReceipt transactionReceipt, String contractAddress, String blockchainNetwork) {
try {
List<TransferEventResponse> transferEvents = getTransactionTransferEvents(transactionReceipt, contractAddress);
if (transferEvents != null && !transferEvents.isEmpty()) {
return transferEvents.stream().map(transferEventResponse -> {
EvmTransaction transferEvent = new EvmTransaction();
transferEvent.setTransactionHash(transferEventResponse.log.getTransactionHash());
transferEvent.setBlockHash(transferEventResponse.log.getBlockHash());
transferEvent.setBlockNumber(transferEventResponse.log.getBlockNumber());
transferEvent.setFromAddress(transferEventResponse.from);
transferEvent.setToAddress(transferEventResponse.to);
transferEvent.setAmount(transferEventResponse.value);
transferEvent.setWalletBalance(erc20BalanceOf(transferEventResponse.to, contractAddress, blockchainNetwork));
return transferEvent;
});
}
Expand Down
Loading

0 comments on commit 4acff9f

Please sign in to comment.