Skip to content

Commit

Permalink
Add all conversion cases
Browse files Browse the repository at this point in the history
  • Loading branch information
tuncpolat committed Aug 29, 2023
1 parent 5bacf82 commit 71971a8
Show file tree
Hide file tree
Showing 4 changed files with 508 additions and 58 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,7 @@

package org.polypheny.db.adapter.ethereum;

import java.io.IOException;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
Expand All @@ -27,16 +25,7 @@
import org.polypheny.db.adapter.DataSource.ExportedColumn;
import org.polypheny.db.adapter.ethereum.CachingStatus.ProcessingState;
import org.polypheny.db.ddl.DdlManager.FieldInformation;
import org.web3j.abi.EventEncoder;
import org.web3j.abi.FunctionReturnDecoder;
import org.web3j.abi.TypeReference;
import org.web3j.abi.datatypes.Event;
import org.web3j.abi.datatypes.Type;
import org.web3j.protocol.Web3j;
import org.web3j.protocol.core.DefaultBlockParameter;
import org.web3j.protocol.core.methods.request.EthFilter;
import org.web3j.protocol.core.methods.response.EthLog;
import org.web3j.protocol.core.methods.response.Log;
import org.web3j.protocol.http.HttpService;

@Slf4j
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,10 @@
@AdapterSettingString(name = "toBlock", description = "Fetch block to (Smart Contract)", defaultValue = "17669155", position = 8, modifiable = true)
@AdapterSettingBoolean(name = "Caching", description = "Cache event data", defaultValue = true, position = 9, modifiable = true)
@AdapterSettingInteger(name = "batchSizeInBlocks", description = "Batch size for caching in blocks", defaultValue = 50, position = 10, modifiable = true)
@AdapterSettingString(name = "CachingAdapterTargetName", description = "Adapter Target Name", defaultValue = "hsqldb", position = 11, modifiable = true) // todo DL: list
@AdapterSettingString(name = "CachingAdapterTargetName", description = "Adapter Target Name", defaultValue = "hsqldb", position = 11, modifiable = true)
@AdapterSettingBoolean(name = "UseManualABI", description = "Cache event data", defaultValue = false, position = 12, modifiable = true)
@AdapterSettingString(name = "ContractABI", description = "Contract ABI", defaultValue = "", position = 13, modifiable = true)
@AdapterSettingString(name = "ContractName", description = "Contract name", defaultValue = "", position = 14, modifiable = true)
@AdapterSettingString(name = "ContractABI", description = "Contract ABI", defaultValue = "", position = 13, modifiable = true, required = false)
@AdapterSettingString(name = "ContractName", description = "Contract name", defaultValue = "", position = 14, modifiable = true, required = false)
public class EthereumDataSource extends DataSource {

public static final String SCHEMA_NAME = "public";
Expand Down Expand Up @@ -337,11 +337,11 @@ private void createExportedColumnsForEvents( Map<String, List<ExportedColumn>> m
String contractName = null;
List<JSONObject> contractEvents = null;
if ( useManualABI == true && !contractABI.isEmpty() && !this.contractName.isEmpty() ) {
if (smartContractAddresses.size() > 1) {
throw new IllegalArgumentException("Only one smart contract address should be provided when using a manual ABI.");
if ( smartContractAddresses.size() > 1 ) {
throw new IllegalArgumentException( "Only one smart contract address should be provided when using a manual ABI." );
}
JSONArray abiArray = new JSONArray(contractABI);
contractEvents = getEventsFromABIArray(abiArray);
JSONArray abiArray = new JSONArray( contractABI );
contractEvents = getEventsFromABIArray( abiArray );
contractName = this.contractName;
} else {
try {
Expand Down Expand Up @@ -470,22 +470,24 @@ protected List<JSONObject> getEventsFromABI( String etherscanApiKey, String cont
return events;
}

protected List<JSONObject> getEventsFromABIArray(JSONArray abiArray) {

protected List<JSONObject> getEventsFromABIArray( JSONArray abiArray ) {
List<JSONObject> events = new ArrayList<>();

// Loop through the ABI
for (int i = 0; i < abiArray.length(); i++) {
JSONObject item = abiArray.getJSONObject(i);
for ( int i = 0; i < abiArray.length(); i++ ) {
JSONObject item = abiArray.getJSONObject( i );

// Check if the item is of type 'event'
if (item.has("type") && "event".equals(item.getString("type"))) {
events.add(item);
if ( item.has( "type" ) && "event".equals( item.getString( "type" ) ) ) {
events.add( item );
}
}

return events;
}


private String getContractName( String contractAddress ) {
try {
URL url = new URL( "https://api.etherscan.io/api?module=contract&action=getsourcecode&address=" + contractAddress + "&apikey=" + etherscanApiKey );
Expand Down Expand Up @@ -545,24 +547,25 @@ private Integer getLengthForType( PolyType type ) {
switch ( type ) {
case VARCHAR:
return 300;
case VARBINARY:
return 32;
default:
return null;
}
}


static PolyType convertToPolyType( String type ) {
// todo: convert all types in evm to polytype
switch ( type ) {
case "bool":
return PolyType.BOOLEAN;
case "address":
return PolyType.VARCHAR;
case "int": // 8 to 256...
case "uint256":
return PolyType.DECIMAL; // todo
default:
return null;
if ( type.equals( "bool" ) ) {
return PolyType.BOOLEAN;
} else if ( type.equals( "address" ) || type.equals( "string" ) ) {
return PolyType.VARCHAR;
} else if ( type.startsWith( "int" ) || type.startsWith( "uint" ) ) {
return PolyType.DECIMAL;
} else if ( type.equals( "bytes" ) || type.startsWith( "bytes" ) ) {
return PolyType.VARCHAR; // for dynamic and fixed-size
} else {
return null;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,14 @@
import org.polypheny.db.transaction.TransactionException;
import org.polypheny.db.transaction.TransactionManager;
import org.web3j.abi.datatypes.Address;
import org.web3j.abi.datatypes.Bool;
import org.web3j.abi.datatypes.Bytes;
import org.web3j.abi.datatypes.DynamicBytes;
import org.web3j.abi.datatypes.Int;
import org.web3j.abi.datatypes.Uint;
import org.web3j.abi.datatypes.generated.Bytes32;
import org.web3j.abi.datatypes.generated.Uint256;
import org.web3j.utils.Numeric;


@Slf4j
Expand Down Expand Up @@ -184,14 +191,7 @@ void writeToStore( String tableName, List<List<Object>> logResults, int targetAd
List<Object> fieldValues = new ArrayList<>();
for ( List<Object> logResult : logResults ) {
Object value = logResult.get( i );
// todo: converting to long (-2^63-1 till 2^63-1) from uint256 (2^256-1) if data is greater than 2^63-1
// how to convert it to bigint? Is there a Poltype that can handle unit256? Double? Evtl. Decimal?
// is Bigint 64-bit signed integer?
if ( value instanceof Address ) {
value = value.toString();
} else if ( value instanceof Uint256 ) {
value = ((Uint256) value).getValue() == null ? null : new BigDecimal(((Uint256) value).getValue());
}
value = convertValueBasedOnType(value);
fieldValues.add( value );
}
i++;
Expand All @@ -217,6 +217,25 @@ protected Map<Integer, CachingStatus> getAllStreamStatus() {
return caches.values().stream().collect( Collectors.toMap( c -> c.sourceAdapterId, ContractCache::getStatus ) );
}

private Object convertValueBasedOnType(Object value) {
if (value instanceof Address) {
return value.toString();
} else if (value instanceof Bool) {
return ((Bool) value).getValue();
} else if (value instanceof DynamicBytes) {
return ((DynamicBytes) value).getValue().toString();
} else if (value instanceof Bytes) {
return value.toString();
} else if (value instanceof Uint) { // Similarly for Uint and its subclasses
BigInteger bigIntValue = ((Uint) value).getValue();
return bigIntValue == null ? null : new BigDecimal(bigIntValue);
} else if (value instanceof Int) { // Similarly for Int and its subclasses
BigInteger bigIntValue = ((Int) value).getValue();
return bigIntValue == null ? null : new BigDecimal(bigIntValue);
}
return value; // return the original value if none of the conditions match
}


@Override
public void run() {
Expand Down
Loading

0 comments on commit 71971a8

Please sign in to comment.