diff --git a/core/src/main/java/com/bloxbean/cardano/yaci/core/model/certs/Certificate.java b/core/src/main/java/com/bloxbean/cardano/yaci/core/model/certs/Certificate.java index b9e190c..2a8ddd1 100644 --- a/core/src/main/java/com/bloxbean/cardano/yaci/core/model/certs/Certificate.java +++ b/core/src/main/java/com/bloxbean/cardano/yaci/core/model/certs/Certificate.java @@ -13,7 +13,20 @@ @JsonSubTypes.Type(value = PoolRetirement.class, name = "POOL_RETIREMENT"), @JsonSubTypes.Type(value = StakeDelegation.class, name = "STAKE_DELEGATION"), @JsonSubTypes.Type(value = StakeDeregistration.class, name = "STAKE_DEREGISTRATION"), - @JsonSubTypes.Type(value = StakeRegistration.class, name = "STAKE_REGISTRATION") + @JsonSubTypes.Type(value = StakeRegistration.class, name = "STAKE_REGISTRATION"), + @JsonSubTypes.Type(value = RegCert.class, name = "REG_CERT"), + @JsonSubTypes.Type(value = UnregCert.class, name = "UNREG_CERT"), + @JsonSubTypes.Type(value = VoteDelegCert.class, name = "VOTE_DELEG_CERT"), + @JsonSubTypes.Type(value = StakeVoteDelegCert.class, name = "STAKE_VOTE_DELEG_CERT"), + @JsonSubTypes.Type(value = StakeRegDelegCert.class, name = "STAKE_REG_DELEG_CERT"), + @JsonSubTypes.Type(value = VoteRegDelegCert.class, name = "VOTE_REG_DELEG_CERT"), + @JsonSubTypes.Type(value = StakeVoteRegDelegCert.class, name = "STAKE_VOTE_REG_DELEG_CERT"), + @JsonSubTypes.Type(value = AuthCommitteeHotCert.class, name = "AUTH_COMMITTEE_HOT_CERT"), + @JsonSubTypes.Type(value = ResignCommitteeColdCert.class, name = "RESIGN_COMMITTEE_COLD_CERT"), + @JsonSubTypes.Type(value = RegDrepCert.class, name = "REG_DREP_CERT"), + @JsonSubTypes.Type(value = UnregDrepCert.class, name = "UNREG_DREP_CERT"), + @JsonSubTypes.Type(value = UpdateDrepCert.class, name = "UPDATE_DREP_CERT") + }) public interface Certificate { CertificateType getType(); diff --git a/core/src/main/java/com/bloxbean/cardano/yaci/core/model/governance/GovActionId.java b/core/src/main/java/com/bloxbean/cardano/yaci/core/model/governance/GovActionId.java index 11d37af..4019a88 100644 --- a/core/src/main/java/com/bloxbean/cardano/yaci/core/model/governance/GovActionId.java +++ b/core/src/main/java/com/bloxbean/cardano/yaci/core/model/governance/GovActionId.java @@ -1,5 +1,9 @@ package com.bloxbean.cardano.yaci.core.model.governance; +import com.bloxbean.cardano.yaci.core.model.jackson.GovActionIdDeserializer; +import com.bloxbean.cardano.yaci.core.model.jackson.GovActionIdSerializer; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; import lombok.*; @Getter @@ -8,6 +12,8 @@ @ToString @EqualsAndHashCode @Builder +@JsonDeserialize(keyUsing = GovActionIdDeserializer.class) +@JsonSerialize(keyUsing = GovActionIdSerializer.class) public class GovActionId { private String transactionId; private Integer gov_action_index; diff --git a/core/src/main/java/com/bloxbean/cardano/yaci/core/model/governance/Voter.java b/core/src/main/java/com/bloxbean/cardano/yaci/core/model/governance/Voter.java index d11e185..ffea148 100644 --- a/core/src/main/java/com/bloxbean/cardano/yaci/core/model/governance/Voter.java +++ b/core/src/main/java/com/bloxbean/cardano/yaci/core/model/governance/Voter.java @@ -1,5 +1,9 @@ package com.bloxbean.cardano.yaci.core.model.governance; +import com.bloxbean.cardano.yaci.core.model.jackson.VoterDeserializer; +import com.bloxbean.cardano.yaci.core.model.jackson.VoterSerializer; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; import lombok.*; @Getter @@ -8,6 +12,8 @@ @ToString @EqualsAndHashCode @Builder +@JsonDeserialize(keyUsing = VoterDeserializer.class) +@JsonSerialize(keyUsing = VoterSerializer.class) public class Voter { private VoterType type; private String hash; //key hash or script hash diff --git a/core/src/main/java/com/bloxbean/cardano/yaci/core/model/jackson/GovActionIdDeserializer.java b/core/src/main/java/com/bloxbean/cardano/yaci/core/model/jackson/GovActionIdDeserializer.java new file mode 100644 index 0000000..d0da351 --- /dev/null +++ b/core/src/main/java/com/bloxbean/cardano/yaci/core/model/jackson/GovActionIdDeserializer.java @@ -0,0 +1,18 @@ +package com.bloxbean.cardano.yaci.core.model.jackson; + +import com.bloxbean.cardano.yaci.core.model.governance.GovActionId; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.KeyDeserializer; +import com.fasterxml.jackson.databind.ObjectMapper; + +import java.io.IOException; + +public class GovActionIdDeserializer extends KeyDeserializer { + private ObjectMapper objectMapper = new ObjectMapper(); + + @Override + public Object deserializeKey(String s, DeserializationContext deserializationContext) + throws IOException { + return objectMapper.readValue(s, GovActionId.class); + } +} diff --git a/core/src/main/java/com/bloxbean/cardano/yaci/core/model/jackson/GovActionIdSerializer.java b/core/src/main/java/com/bloxbean/cardano/yaci/core/model/jackson/GovActionIdSerializer.java new file mode 100644 index 0000000..9ac5f19 --- /dev/null +++ b/core/src/main/java/com/bloxbean/cardano/yaci/core/model/jackson/GovActionIdSerializer.java @@ -0,0 +1,17 @@ +package com.bloxbean.cardano.yaci.core.model.jackson; + +import com.bloxbean.cardano.yaci.core.model.governance.GovActionId; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializerProvider; + +import java.io.IOException; + +public class GovActionIdSerializer extends JsonSerializer { + @Override + public void serialize(GovActionId govActionId, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { + ObjectMapper mapper = new ObjectMapper(); + jsonGenerator.writeFieldName(mapper.writeValueAsString(govActionId)); + } +} diff --git a/core/src/main/java/com/bloxbean/cardano/yaci/core/model/jackson/VoterDeserializer.java b/core/src/main/java/com/bloxbean/cardano/yaci/core/model/jackson/VoterDeserializer.java new file mode 100644 index 0000000..baec035 --- /dev/null +++ b/core/src/main/java/com/bloxbean/cardano/yaci/core/model/jackson/VoterDeserializer.java @@ -0,0 +1,18 @@ +package com.bloxbean.cardano.yaci.core.model.jackson; + +import com.bloxbean.cardano.yaci.core.model.governance.Voter; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.KeyDeserializer; +import com.fasterxml.jackson.databind.ObjectMapper; + +import java.io.IOException; + +public class VoterDeserializer extends KeyDeserializer { + private ObjectMapper objectMapper = new ObjectMapper(); + + @Override + public Object deserializeKey(String s, DeserializationContext deserializationContext) + throws IOException { + return objectMapper.readValue(s, Voter.class); + } +} diff --git a/core/src/main/java/com/bloxbean/cardano/yaci/core/model/jackson/VoterSerializer.java b/core/src/main/java/com/bloxbean/cardano/yaci/core/model/jackson/VoterSerializer.java new file mode 100644 index 0000000..d5eac64 --- /dev/null +++ b/core/src/main/java/com/bloxbean/cardano/yaci/core/model/jackson/VoterSerializer.java @@ -0,0 +1,17 @@ +package com.bloxbean.cardano.yaci.core.model.jackson; + +import com.bloxbean.cardano.yaci.core.model.governance.Voter; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializerProvider; + +import java.io.IOException; + +public class VoterSerializer extends JsonSerializer { + @Override + public void serialize(Voter voter, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { + ObjectMapper mapper = new ObjectMapper(); + jsonGenerator.writeFieldName(mapper.writeValueAsString(voter)); + } +} diff --git a/helper/src/integrationTest/java/com/bloxbean/cardano/yaci/helper/BaseTest.java b/helper/src/integrationTest/java/com/bloxbean/cardano/yaci/helper/BaseTest.java index 12ef2fb..4620370 100644 --- a/helper/src/integrationTest/java/com/bloxbean/cardano/yaci/helper/BaseTest.java +++ b/helper/src/integrationTest/java/com/bloxbean/cardano/yaci/helper/BaseTest.java @@ -9,5 +9,5 @@ public class BaseTest { protected long protocolMagic = Constants.PREPROD_PROTOCOL_MAGIC; protected Point knownPoint = new Point(13003663, "b896e43a25de269cfc47be7afbcbf00cad41a5011725c2732393f1b4508cf41d"); - protected String nodeSocketFile = "/Users/satya/work/cardano-node/preprod/db/node.socket"; + protected String nodeSocketFile = "/Users/satya/work/cardano-node/preprod-8.1.2/db/node.socket"; } diff --git a/helper/src/integrationTest/java/com/bloxbean/cardano/yaci/helper/ConwayEraIT.java b/helper/src/integrationTest/java/com/bloxbean/cardano/yaci/helper/ConwayEraIT.java index 260b30c..fc5e6f0 100644 --- a/helper/src/integrationTest/java/com/bloxbean/cardano/yaci/helper/ConwayEraIT.java +++ b/helper/src/integrationTest/java/com/bloxbean/cardano/yaci/helper/ConwayEraIT.java @@ -13,25 +13,30 @@ import org.junit.jupiter.api.Test; import java.time.Duration; +import java.util.ArrayList; import java.util.List; import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Collectors; +import static org.assertj.core.api.Assertions.assertThat; @Slf4j public class ConwayEraIT extends BaseTest{ @Test void syncTest() throws Exception { - //BlockSync blockSync = new BlockSync(Constants.SANCHONET_PUBLIC_RELAY_ADDR, Constants.SANCHONET_PUBLIC_RELAY_PORT, Constants.SANCHONET_PROTOCOL_MAGIC, Constants.WELL_KNOWN_SANCHONET_POINT); BlockSync blockSync = new BlockSync(Constants.SANCHONET_PUBLIC_RELAY_ADDR, Constants.SANCHONET_PUBLIC_RELAY_PORT, Constants.SANCHONET_PROTOCOL_MAGIC, Constants.WELL_KNOWN_SANCHONET_POINT); -// BlockSync blockSync = new BlockSync("localhost", 30000, Constants.PREPROD_PROTOCOL_MAGIC, Constants.WELL_KNOWN_PREPROD_POINT); + CountDownLatch countDownLatch = new CountDownLatch(5); + List blocks = new ArrayList<>(); blockSync.startSync(Point.ORIGIN, new BlockChainDataListener() { public void onBlock(Era era, Block block, List transactions) { System.out.println(block.getHeader().getHeaderBody().getBlockNumber()); System.out.println(block.getHeader().getHeaderBody().getBlockHash()); System.out.println(block.getHeader().getHeaderBody().getSlot()); System.out.println("# of transactions >> " + transactions.size()); + blocks.add(block); + countDownLatch.countDown(); } @Override @@ -45,15 +50,16 @@ public void onByronEbBlock(ByronEbBlock byronEbBlock) { } }); - while (true) - Thread.sleep(5000); + countDownLatch.await(30, TimeUnit.SECONDS); + assertThat(blocks).hasSize(5); } @Test void syncFromTip() throws Exception { - //BlockSync blockSync = new BlockSync(Constants.SANCHONET_PUBLIC_RELAY_ADDR, Constants.SANCHONET_PUBLIC_RELAY_PORT, Constants.SANCHONET_PROTOCOL_MAGIC, Constants.WELL_KNOWN_SANCHONET_POINT); BlockSync blockSync = new BlockSync(Constants.SANCHONET_PUBLIC_RELAY_ADDR, Constants.SANCHONET_PUBLIC_RELAY_PORT, Constants.SANCHONET_PROTOCOL_MAGIC, Constants.WELL_KNOWN_SANCHONET_POINT); -// BlockSync blockSync = new BlockSync("localhost", 30000, Constants.PREPROD_PROTOCOL_MAGIC, Constants.WELL_KNOWN_PREPROD_POINT); + + CountDownLatch countDownLatch = new CountDownLatch(1); + List blocks = new ArrayList<>(); blockSync.startSyncFromTip(new BlockChainDataListener() { public void onBlock(Era era, Block block, List transactions) { System.out.println(block.getHeader().getHeaderBody().getBlockNumber()); @@ -64,6 +70,8 @@ public void onBlock(Era era, Block block, List transactions) { System.out.println("Proposal Procedures: " + transactions.stream().map(t -> t.getBody().getProposalProcedures()).collect(Collectors.toList())); System.out.println("Current Treasury Value: " + transactions.stream().map(t -> t.getBody().getCurrentTreasuryValue()).collect(Collectors.toList())); System.out.println("Dontation: " + transactions.stream().map(t -> t.getBody().getDonation()).collect(Collectors.toList())); + blocks.add(block); + countDownLatch.countDown(); } @Override @@ -77,8 +85,8 @@ public void onByronEbBlock(ByronEbBlock byronEbBlock) { } }); - while (true) - Thread.sleep(5000); + countDownLatch.await(60, TimeUnit.SECONDS); + assertThat(blocks).hasSize(1); } @Test @@ -86,10 +94,7 @@ public void fetchBlock() throws InterruptedException { BlockFetcher blockFetcher = new BlockFetcher(Constants.SANCHONET_PUBLIC_RELAY_ADDR, Constants.SANCHONET_PUBLIC_RELAY_PORT, Constants.SANCHONET_PROTOCOL_MAGIC); CountDownLatch countDownLatch = new CountDownLatch(1); - AtomicInteger count = new AtomicInteger(0); - -// List blocks = new ArrayList<>(); blockFetcher.start(block -> { if (count.get() % 1000 == 0) log.info("Block >>> {} -- {} -- {} -- {}", block.getHeader().getHeaderBody().getBlockNumber(), @@ -97,24 +102,19 @@ public void fetchBlock() throws InterruptedException { block.getHeader().getHeaderBody().getSlot(), block.getEra()); count.incrementAndGet(); -// countDownLatch.countDown(); - + countDownLatch.countDown(); }); - Point knownPoint = new Point(20, "6a7d97aae2a65ca790fd14802808b7fce00a3362bd7b21c4ed4ccb4296783b98"); + TipFinder tipFinder = new TipFinder(Constants.SANCHONET_PUBLIC_RELAY_ADDR, Constants.SANCHONET_PUBLIC_RELAY_PORT, Constants.WELL_KNOWN_SANCHONET_POINT, Constants.SANCHONET_PROTOCOL_MAGIC); Tip tip = tipFinder.find().block(Duration.ofSeconds(5)); - //Byron blocks -// Point from = new Point(0, "f0f7892b5c333cffc4b3c4344de48af4cc63f55e44936196f365a9ef2244134f"); -// Point to = new Point(5, "365201e928da50760fce4bdad09a7338ba43a43aff1c0e8d3ec458388c932ec8"); Point from = Constants.WELL_KNOWN_SANCHONET_POINT; - Point to = tip.getPoint();//new Point(8569937, "8264c74dcdf7afc02e0c176090af367b2662326d623a478710d54e22bf749ebd"); + Point to = tip.getPoint(); blockFetcher.fetch(from, to); - while (true) - Thread.sleep(5000); -// blockFetcher.shutdown(); + countDownLatch.await(30, TimeUnit.SECONDS); -// assertThat(blocks.get(0).getHeader().getHeaderBody().getBlockNumber()).isEqualTo(287622); + blockFetcher.shutdown(); + assertThat(count.get()).isGreaterThanOrEqualTo(1); } } diff --git a/helper/src/test/java/com/bloxbean/cardano/yaci/helper/JsonSerializationTest.java b/helper/src/test/java/com/bloxbean/cardano/yaci/helper/JsonSerializationTest.java new file mode 100644 index 0000000..628c7fb --- /dev/null +++ b/helper/src/test/java/com/bloxbean/cardano/yaci/helper/JsonSerializationTest.java @@ -0,0 +1,114 @@ +package com.bloxbean.cardano.yaci.helper; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.jupiter.api.Test; +import com.bloxbean.cardano.yaci.helper.model.Transaction; + +public class JsonSerializationTest { + + @Test + void deserTransaction() throws JsonProcessingException { + String txnJson = " {\n" + + " \"blockNumber\" : 283100,\n" + + " \"slot\" : 12912862,\n" + + " \"txHash\" : \"b9ebe459c3ba8e890f951dacb50cba6fa02cf099c6308c7abd26cf616bf26ca5\",\n" + + " \"body\" : {\n" + + " \"txHash\" : \"b9ebe459c3ba8e890f951dacb50cba6fa02cf099c6308c7abd26cf616bf26ca5\",\n" + + " \"cbor\" : null,\n" + + " \"inputs\" : [ {\n" + + " \"transactionId\" : \"6d2174d3956d8eb2b3e1e198e817ccf1332a599d5d7320400bfd820490d706be\",\n" + + " \"index\" : 0\n" + + " } ],\n" + + " \"outputs\" : [ {\n" + + " \"address\" : \"addr_test1qpe6s9amgfwtu9u6lqj998vke6uncswr4dg88qqft5d7f67kfjf77qy57hqhnefcqyy7hmhsygj9j38rj984hn9r57fswc4wg0\",\n" + + " \"amounts\" : [ {\n" + + " \"unit\" : \"lovelace\",\n" + + " \"policyId\" : null,\n" + + " \"assetName\" : \"lovelace\",\n" + + " \"quantity\" : 48000000\n" + + " } ],\n" + + " \"datumHash\" : null,\n" + + " \"inlineDatum\" : null,\n" + + " \"scriptRef\" : null\n" + + " } ],\n" + + " \"fee\" : 2000000,\n" + + " \"ttl\" : 0,\n" + + " \"certificates\" : [ ],\n" + + " \"withdrawals\" : null,\n" + + " \"update\" : null,\n" + + " \"auxiliaryDataHash\" : null,\n" + + " \"validityIntervalStart\" : 0,\n" + + " \"mint\" : [ ],\n" + + " \"scriptDataHash\" : \"192d0c0c2c2320e843e080b5f91a9ca35155bc50f3ef3bfdbc72c1711b86367e\",\n" + + " \"collateralInputs\" : [ {\n" + + " \"transactionId\" : \"99c2ef8e340d5991b1acfcb2a3bf06145ab139f0b10837fb8862cf0ec2324d03\",\n" + + " \"index\" : 0\n" + + " } ],\n" + + " \"requiredSigners\" : null,\n" + + " \"netowrkId\" : 0,\n" + + " \"collateralReturn\" : {\n" + + " \"address\" : \"addr_test1qpe6s9amgfwtu9u6lqj998vke6uncswr4dg88qqft5d7f67kfjf77qy57hqhnefcqyy7hmhsygj9j38rj984hn9r57fswc4wg0\",\n" + + " \"amounts\" : [ {\n" + + " \"unit\" : \"lovelace\",\n" + + " \"policyId\" : null,\n" + + " \"assetName\" : \"lovelace\",\n" + + " \"quantity\" : 7000000\n" + + " } ],\n" + + " \"datumHash\" : null,\n" + + " \"inlineDatum\" : null,\n" + + " \"scriptRef\" : null\n" + + " },\n" + + " \"totalCollateral\" : 3000000,\n" + + " \"referenceInputs\" : null,\n" + + " \"votingProcedures\" : null,\n" + + " \"proposalProcedures\" : null,\n" + + " \"currentTreasuryValue\" : null,\n" + + " \"donation\" : null\n" + + " },\n" + + " \"utxos\" : [ ],\n" + + " \"collateralReturnUtxo\" : {\n" + + " \"txHash\" : \"b9ebe459c3ba8e890f951dacb50cba6fa02cf099c6308c7abd26cf616bf26ca5\",\n" + + " \"index\" : 1,\n" + + " \"address\" : \"addr_test1qpe6s9amgfwtu9u6lqj998vke6uncswr4dg88qqft5d7f67kfjf77qy57hqhnefcqyy7hmhsygj9j38rj984hn9r57fswc4wg0\",\n" + + " \"amounts\" : [ {\n" + + " \"unit\" : \"lovelace\",\n" + + " \"policyId\" : null,\n" + + " \"assetName\" : \"lovelace\",\n" + + " \"quantity\" : 7000000\n" + + " } ],\n" + + " \"datumHash\" : null,\n" + + " \"inlineDatum\" : null,\n" + + " \"scriptRef\" : null\n" + + " },\n" + + " \"witnesses\" : {\n" + + " \"vkeyWitnesses\" : [ {\n" + + " \"key\" : \"53442c73a8bdbd7bdb59d033bd35bfb3968784eb85be3955dc025de491744f92\",\n" + + " \"signature\" : \"6f4815ac017228d22290a1276134c34e1a2f970e9816a9a0df0bcaa5fdcc0d636e4d13f7572ce8f826d5302a7a12fd5cfd3ca306970b714c632ddd338db96b08\"\n" + + " } ],\n" + + " \"nativeScripts\" : [ ],\n" + + " \"bootstrapWitnesses\" : [ ],\n" + + " \"plutusV1Scripts\" : [ ],\n" + + " \"datums\" : [ {\n" + + " \"cbor\" : \"19077a\",\n" + + " \"json\" : \"\"\n" + + " } ],\n" + + " \"redeemers\" : [ {\n" + + " \"cbor\" : \"840000187b820a0a\"\n" + + " } ],\n" + + " \"plutusV2Scripts\" : [ {\n" + + " \"type\" : \"2\",\n" + + " \"content\" : \"4746010000222601\"\n" + + " } ],\n" + + " \"plutusV3Scripts\" : [ ]\n" + + " },\n" + + " \"auxData\" : null,\n" + + " \"invalid\" : true\n" + + " }\n"; + + ObjectMapper objectMapper = new ObjectMapper(); + Transaction transaction = objectMapper.readValue(txnJson, Transaction.class); + System.out.println(transaction); + + } +}