Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
io.keyko.monitoring.services.EventLogService Maven / Gradle / Ivy
Go to download
Kafka stream processors that enrich data generated with web3-monitoring agent
package io.keyko.monitoring.services;
import io.keyko.monitoring.exceptions.AbiNotFoundException;
import io.keyko.monitoring.exceptions.EtherscanException;
import io.keyko.monitoring.exceptions.EventFromLogException;
import io.keyko.monitoring.exceptions.TypeConversionException;
import io.keyko.monitoring.model.ContractData;
import io.keyko.monitoring.schemas.*;
import org.apache.log4j.Logger;
import org.web3j.abi.EventEncoder;
import org.web3j.abi.FunctionReturnDecoder;
import org.web3j.abi.datatypes.Event;
import org.web3j.abi.datatypes.Type;
import org.web3j.protocol.core.methods.response.AbiDefinition;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class EventLogService {
private static Logger log = Logger.getLogger(EventLogService.class);
public static EventRecord getEventFromLog(LogRecord log, String getContractAbiUrl, String apiKey) throws EventFromLogException, TypeConversionException {
String contractAddress = log.getAddress();
ContractData contractData = null;
try {
contractData = EtherscanService.getContractData(getContractAbiUrl, contractAddress, apiKey);
} catch (EtherscanException e) {
throw new EventFromLogException("Error getting the data from Contract", e);
}
List eventsAbiDefinition = getAbiDefinitionByType("event", contractData.getAbiDefinitionList());
AbiDefinition eventAbi = null;
try {
eventAbi = getEventAbi(log, eventsAbiDefinition);
} catch (AbiNotFoundException e) {
throw new EventFromLogException("Error getting the ABI Definition for the event", e);
}
Event event = getEventFromAbi(eventAbi);
List indexed = getIndexedParametersFromLog(event, log);
List nonIndexed = getNonIndexedParametersFromLog(event, log);
return generateEventRecord(contractData.getName(),
event.getName(),
getEventHashFromAbi(eventAbi),
web3ToMonitoringType(indexed, eventAbi, true),
web3ToMonitoringType(nonIndexed, eventAbi, false),
log);
}
private static ContractEventStatus getEventStatus(LogStatus logStatus){
switch(logStatus){
case CONFIRMED: return ContractEventStatus.CONFIRMED;
case UNCONFIRMED: return ContractEventStatus.UNCONFIRMED;
case INVALIDATED: return ContractEventStatus.INVALIDATED;
}
return ContractEventStatus.UNCONFIRMED;
}
private static EventRecord generateEventRecord(String contractName, String eventName, String eventHash, List indexedParameters, List nonIndexedParameters, LogRecord logRecord){
EventRecord eventRecord = new EventRecord();
eventRecord.setRetries(logRecord.getRetries());
eventRecord.setId(logRecord.getId());
eventRecord.setContractName(contractName);
eventRecord.setBlockNumber(logRecord.getBlockNumber());
eventRecord.setName(eventName);
eventRecord.setStatus(getEventStatus(logRecord.getStatus()));
eventRecord.setBlockHash(logRecord.getBlockHash());
eventRecord.setAddress(logRecord.getAddress());
eventRecord.setEventSpecificationSignature(eventHash);
eventRecord.setFilterId(eventName);
eventRecord.setLogIndex(logRecord.getLogIndex());
eventRecord.setNetworkName(logRecord.getNetworkName());
eventRecord.setNodeName(logRecord.getNodeName());
eventRecord.setTransactionHash(logRecord.getTransactionHash());
eventRecord.setIndexedParameters(indexedParameters);
eventRecord.setNonIndexedParameters(nonIndexedParameters);
if (log.isDebugEnabled())
printEventRecord(eventRecord);
return eventRecord;
}
private static void printEventRecord(EventRecord eventRecord){
log.debug("Generated EventRecord: ");
log.debug("ID: " + eventRecord.getId());
log.debug("Contract name: " + eventRecord.getContractName());
log.debug("Block number : " + eventRecord.getBlockNumber());
log.debug("Name: " + eventRecord.getName());
log.debug("Status: " + eventRecord.getStatus());
log.debug("Block haash : " + eventRecord.getBlockHash());
log.debug("Address: " + eventRecord.getAddress());
log.debug("EventSpecificationSignature: " + eventRecord.getEventSpecificationSignature());
log.debug("FilterId: " + eventRecord.getFilterId());
log.debug("LogIndex: " + eventRecord.getLogIndex());
log.debug("NetworkName: " + eventRecord.getNetworkName());
log.debug("NodeName: " + eventRecord.getNodeName());
log.debug("TransactionHash: " + eventRecord.getTransactionHash());
log.debug("Indexed Parameters: ");
printParameters(eventRecord.getIndexedParameters());
log.debug("Non Indexed Parameters: ");
printParameters(eventRecord.getNonIndexedParameters());
}
private static void printParameters(List parameters){
for(Object o:parameters){
if (o instanceof NumberParameter) {
NumberParameter np = (NumberParameter) o;
log.debug("Parameter Name: " + np.getName());
log.debug("Parameter Type: " + np.getType());
log.debug("Parameter Value: " + np.getValue());
log.debug("Parameter Number Value: " + np.getNumberValue());
}
else if (o instanceof StringParameter) {
StringParameter sp = (StringParameter) o;
log.debug("Parameter Name: " + sp.getName());
log.debug("Parameter Type: " + sp.getType());
log.debug("Parameter Value: " + sp.getValue());
}
}
}
private static List web3ToMonitoringType(List parameters, AbiDefinition eventAbi, Boolean indexed) throws TypeConversionException {
List monitoringParameters = new ArrayList<>();
List namedTypes = eventAbi.getInputs()
.stream()
.filter( input -> input.isIndexed() == indexed)
.collect(Collectors.toList());
for(int i=0; i getNonIndexedParametersFromLog(Event event, LogRecord log) {
if (event.getNonIndexedParameters().isEmpty() ) {
return Collections.EMPTY_LIST;
}
return FunctionReturnDecoder.decode(
log.getData(), event.getNonIndexedParameters());
}
private static List getIndexedParametersFromLog(Event event, LogRecord log) {
if (event.getIndexedParameters().isEmpty() ) {
return Collections.EMPTY_LIST;
}
List topics = log.getTopics().stream().map( o -> o.toString()).collect(Collectors.toList());
final List encodedParameters = topics.subList(1, topics.size());
return IntStream.range(0, encodedParameters.size())
.mapToObj(i -> FunctionReturnDecoder.decodeIndexedValue(topics.get(i), event.getIndexedParameters().get(i)))
.collect(Collectors.toList());
}
private static String getEventHashFromAbi(AbiDefinition eventAbi) throws EventFromLogException {
return EventEncoder.encode(getEventFromAbi(eventAbi));
}
public static Event getEventFromAbi(AbiDefinition eventAbi) throws EventFromLogException {
List params = eventAbi.getInputs();
List> typeReferences = new ArrayList<>();
for(AbiDefinition.NamedType param: params){
org.web3j.abi.TypeReference type = null;
try {
type = org.web3j.abi.TypeReference.makeTypeReference(param.getType(), param.isIndexed(), false);
} catch (ClassNotFoundException e) {
String message = "Error making type reference";
log.error(message + " "+ e.getMessage());
throw new EventFromLogException(message, e);
}
typeReferences.add(type);
}
return new Event(eventAbi.getName(), typeReferences);
}
public static AbiDefinition getEventAbi(LogRecord log, List eventsAbiDefinition ) throws AbiNotFoundException{
String eventLogHash = log.getTopics().get(0);
AbiDefinition abiDefinition = eventsAbiDefinition
.stream()
.filter( eventAbi ->
{
// TODO HANDLE EXCEPTION
Boolean found = false;
try {
found = getEventHashFromAbi(eventAbi).equalsIgnoreCase(eventLogHash);
} catch (Exception e) {
e.printStackTrace();
}
return found;
})
.findFirst()
.orElse(null);
if (abiDefinition==null)
throw new AbiNotFoundException("The ABI for event " + eventLogHash + "was not found in the current ABI Definition ");
return abiDefinition;
}
public static List getAbiDefinitionByType(String type, List abiDefinitionList){
return abiDefinitionList
.stream()
.filter(abi -> abi.getType().equalsIgnoreCase(type))
.collect(Collectors.toList());
}
}