Skip to content

Commit

Permalink
Feat/implement construction metadata (#82)
Browse files Browse the repository at this point in the history
* implemented /metadata

* implemented construction metadata

* chore: added postman tests

* adjusted readme

* chore: fixed NetworkEnum

* chore: added CardanoConfigService to get ProtocolParams from configfile

* chore: added CardanoConfigService to get ProtocolParams from configfile

* chore: fixed names of config file
  • Loading branch information
Kammerlo authored Mar 11, 2024
1 parent 90134b1 commit fef724c
Show file tree
Hide file tree
Showing 19 changed files with 618 additions and 78 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/integration-test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ jobs:
- uses: actions/checkout@v3
- name: "Set up environment"
run: docker compose --env-file .env.IntegrationTest -f docker-integration-test-environment.yaml up --build -d --wait
- name: "Wait for node to be populated"
run: "sleep 30s"
- name: "Install Node"
uses: actions/setup-node@v1
with:
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ to fetch the data from the node.
- Construction API
- [x] /construction/derive
- [ ] /construction/preprocess
- [ ] /construction/metadata
- [x] /construction/metadata
- [ ] /construction/payloads
- [ ] /construction/combine
- [ ] /construction/parse
Expand Down Expand Up @@ -52,10 +52,10 @@ to fetch the data from the node.

### How to run integration tests

- Run `docker compose --env-file .env.IntegrationTest -f docker-integration-test-environment.yaml up --build -d`
- Run `docker compose --env-file .env.IntegrationTest -f docker-integration-test-environment.yaml up --build -d --wait`
- Using CLI
- Install newman `npm install -g newman` (Node version 14+ needed)
- Run `newman run ./postmanTests/rosetta-java.postman_collection.json -e ./postmanTests/Rosetta-java-env.postman_environment -r cli`
- Run `newman run ./postmanTests/rosetta-java.postman_collection.json -e ./postmanTests/Rosetta-java-env.postman_environment.json -r cli`
- Using Postman
- Install [Postman](https://www.postman.com)
- Import the collection `./postmanTests/rosetta-java.postman_collection.json`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import org.cardanofoundation.rosetta.api.model.constants.Constants;
import org.cardanofoundation.rosetta.api.model.dto.*;
import org.cardanofoundation.rosetta.api.model.dto.TransactionDto;
import org.cardanofoundation.rosetta.api.model.entity.ProtocolParams;
import org.cardanofoundation.rosetta.api.model.enumeration.NetworkEnum;
import org.cardanofoundation.rosetta.api.model.rest.TransactionMetadata;
import org.cardanofoundation.rosetta.api.model.rosetta.BlockMetadata;
Expand Down Expand Up @@ -232,6 +233,20 @@ public static AccountCoinsResponse mapToAccountCoinsResponse(BlockDto block, Lis
.build()).build()).build()).toList()).build();

}

public static ConstructionMetadataResponse mapToMetadataResponse(ProtocolParams protocolParams, Long ttl, Long suggestedFee) {
return ConstructionMetadataResponse.builder()
.metadata(Map.of("protocol_parameters", protocolParams, "ttl", ttl))
.suggestedFee(List.of(Amount.builder()
.value(suggestedFee.toString())
.currency(Currency.builder()
.decimals(ADA_DECIMALS)
.symbol(ADA)
.build())
.build()))
.build();
}

}


Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package org.cardanofoundation.rosetta.api.model.entity;

import io.hypersistence.utils.hibernate.type.json.JsonType;
import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
import lombok.extern.slf4j.Slf4j;
import org.hibernate.annotations.Type;

@Data
@NoArgsConstructor
@AllArgsConstructor
@SuperBuilder
@Entity
@Table(name = "epoch_param")
@Slf4j
public class EpochParamEntity extends BlockAwareEntity {
@Id
@Column(name = "epoch")
private Integer epoch;

@Type(JsonType.class)
@Column(name = "params", columnDefinition = "json")
private ProtocolParams params;

@Column(name = "cost_model_hash")
private String costModelHash;

@Column(name = "slot")
private Long slot;

@PrePersist
public void preSave() {
if (this.getParams() == null)
return;

//reset these fields
if (this.getParams().getCostModels() != null)
this.getParams().setCostModels(null);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,233 @@
package org.cardanofoundation.rosetta.api.model.entity;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.PropertyNamingStrategies;
import com.fasterxml.jackson.databind.annotation.JsonNaming;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.json.JSONObject;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Map;

@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
public class ProtocolParams {
private Integer minFeeA; //0
private Integer minFeeB; //1
private Integer maxBlockSize; //2
private Integer maxTxSize; //3
private Integer maxBlockHeaderSize; //4
private BigInteger keyDeposit; //5
private BigInteger poolDeposit; //6
private Integer maxEpoch; //7
@JsonProperty("nopt")
private Integer nOpt; //8
private BigDecimal poolPledgeInfluence; //rational //9
private BigDecimal expansionRate; //unit interval //10
private BigDecimal treasuryGrowthRate; //11
private BigDecimal decentralisationParam; //12
private String extraEntropy; //13
private Integer protocolMajorVer; //14
private Integer protocolMinorVer; //14
private BigInteger minUtxo; //TODO //15

private BigInteger minPoolCost; //16
private BigInteger adaPerUtxoByte; //17
//private String nonce;

//Alonzo changes
private Map<String, long[]> costModels; //18
private String costModelsHash;

//ex_unit_prices
private BigDecimal priceMem; //19
private BigDecimal priceStep; //19

//max tx ex units
private BigInteger maxTxExMem; //20
private BigInteger maxTxExSteps; //20

//max block ex units
private BigInteger maxBlockExMem; //21
private BigInteger maxBlockExSteps; //21

private Long maxValSize; //22

private Integer collateralPercent; //23
private Integer maxCollateralInputs; //24

// //Cost per UTxO word for Alonzo.
// //Cost per UTxO byte for Babbage and later.
// private String coinsPerUtxoSize;
// @Deprecated
// private String coinsPerUtxoWord;

//Conway era fields
// private PoolVotingThresholds poolVotingThresholds; //25
// private DrepVoteThresholds drepVotingThresholds; //26
private Integer committeeMinSize; //27
private Integer committeeMaxTermLength; //28
private Integer govActionLifetime; //29
private BigInteger govActionDeposit; //30
private BigInteger drepDeposit; //31
private Integer drepActivity; //32

// TODO clarify if parameters are correctly set
public static ProtocolParams fromJSONObject(JSONObject shelleyJsonObject) {
ProtocolParams p = new ProtocolParams();
JSONObject shelleyProtocolParams = shelleyJsonObject.getJSONObject("protocolParams");
p.setMinFeeA(shelleyProtocolParams.getInt("minFeeA"));
p.setMinFeeB(shelleyProtocolParams.getInt("minFeeB"));
p.setMaxBlockSize(shelleyProtocolParams.getInt("maxBlockBodySize"));
p.setMaxTxSize(shelleyProtocolParams.getInt("maxTxSize"));
p.setMaxBlockHeaderSize(shelleyProtocolParams.getInt("maxBlockHeaderSize"));
p.setKeyDeposit(shelleyProtocolParams.getBigInteger("keyDeposit"));
p.setPoolDeposit(shelleyProtocolParams.getBigInteger("poolDeposit"));
p.setNOpt(shelleyProtocolParams.getInt("nOpt"));
p.setDecentralisationParam(shelleyProtocolParams.getBigDecimal("decentralisationParam"));
p.setExtraEntropy(shelleyProtocolParams.getJSONObject("extraEntropy").getString("tag"));
JSONObject protolVersion = shelleyProtocolParams.getJSONObject("protocolVersion");
p.setProtocolMajorVer(protolVersion.getInt("major"));
p.setProtocolMinorVer(protolVersion.getInt("minor"));
p.setMinUtxo(shelleyProtocolParams.getBigInteger("minUTxOValue"));
p.setMinPoolCost(shelleyProtocolParams.getBigInteger("minPoolCost"));
p.setAdaPerUtxoByte(shelleyProtocolParams.getBigInteger("minFeeA"));

return p;
}

public void merge(ProtocolParams other) {
if (this.minFeeA == null) {
this.minFeeA = other.minFeeA;
}
if (this.minFeeB == null) {
this.minFeeB = other.minFeeB;
}
if (this.maxBlockSize == null) {
this.maxBlockSize = other.maxBlockSize;
}
if (this.maxTxSize == null) {
this.maxTxSize = other.maxTxSize;
}
if (this.maxBlockHeaderSize == null) {
this.maxBlockHeaderSize = other.maxBlockHeaderSize;
}
if (this.keyDeposit == null) {
this.keyDeposit = other.keyDeposit;
}
if (this.poolDeposit == null) {
this.poolDeposit = other.poolDeposit;
}
if (this.maxEpoch == null) {
this.maxEpoch = other.maxEpoch;
}
if (this.nOpt == null) {
this.nOpt = other.nOpt;
}
if (this.poolPledgeInfluence == null) {
this.poolPledgeInfluence = other.poolPledgeInfluence;
}
if (this.expansionRate == null) {
this.expansionRate = other.expansionRate;
}
if (this.treasuryGrowthRate == null) {
this.treasuryGrowthRate = other.treasuryGrowthRate;
}
if (this.decentralisationParam == null) {
this.decentralisationParam = other.decentralisationParam;
}
if (this.extraEntropy == null) {
this.extraEntropy = other.extraEntropy;
}
if (this.protocolMajorVer == null) {
this.protocolMajorVer = other.protocolMajorVer;
}
if (this.protocolMinorVer == null) {
this.protocolMinorVer = other.protocolMinorVer;
}
if (this.minUtxo == null) {
this.minUtxo = other.minUtxo;
}
if (this.minPoolCost == null) {
this.minPoolCost = other.minPoolCost;
}
if (this.adaPerUtxoByte == null) {
this.adaPerUtxoByte = other.adaPerUtxoByte;
}
if (this.costModels == null) {
if (this.costModels == null) {
this.costModels = other.getCostModels();
} else {
var keys = other.getCostModels().keySet();
keys.forEach(key -> this.costModels.put(key, other.costModels.get(key)));
}
}

if (this.costModelsHash == null) {
this.costModelsHash = other.costModelsHash;
}

if (this.priceMem == null) {
this.priceMem = other.priceMem;
}
if (this.priceStep == null) {
this.priceStep = other.priceStep;
}
if (this.maxTxExMem == null) {
this.maxTxExMem = other.maxTxExMem;
}
if (this.maxTxExSteps == null) {
this.maxTxExSteps = other.maxTxExSteps;
}
if (this.maxBlockExMem == null) {
this.maxBlockExMem = other.maxBlockExMem;
}
if (this.maxBlockExSteps == null) {
this.maxBlockExSteps = other.maxBlockExSteps;
}
if (this.maxValSize == null) {
this.maxValSize = other.maxValSize;
}
if (this.collateralPercent == null) {
this.collateralPercent = other.collateralPercent;
}
if (this.maxCollateralInputs == null) {
this.maxCollateralInputs = other.maxCollateralInputs;
}
// if (other.poolVotingThresholds == null) {
// this.poolVotingThresholds = other.poolVotingThresholds;
// }
// if (other.drepVotingThresholds == null) {
// this.drepVotingThresholds = other.drepVotingThresholds;
// }
if (this.committeeMinSize == null) {
this.committeeMinSize = other.committeeMinSize;
}
if (this.committeeMaxTermLength == null) {
this.committeeMaxTermLength = other.committeeMaxTermLength;
}
if (this.govActionLifetime == null) {
this.govActionLifetime = other.govActionLifetime;
}
if (this.govActionDeposit == null) {
this.govActionDeposit = other.govActionDeposit;
}
if (this.drepDeposit == null) {
this.drepDeposit = other.drepDeposit;
}
if (this.drepActivity == null) {
this.drepActivity = other.drepActivity;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@

import com.bloxbean.cardano.client.common.model.Network;
import com.bloxbean.cardano.client.common.model.Networks;
import lombok.Getter;

@Getter
public enum NetworkEnum {

MAINNET("mainnet", Networks.mainnet()),
PREPROD("preprod", Networks.testnet()),
PREPROD("preprod", Networks.preprod()),
TESTNET("testnet", Networks.testnet()),
DEVNET("devnet", new Network(0b0000, 42));

Expand All @@ -18,11 +20,7 @@ public enum NetworkEnum {
this.network = network;
}

public String getValue() {
return value;
}

final public Network getNetwork() {
public final Network getNetwork() {
return network;
}

Expand Down
Loading

0 comments on commit fef724c

Please sign in to comment.