Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(domain): adds domain model, based on APIs, and various inputs #154

Draft
wants to merge 13 commits into
base: main
Choose a base branch
from

Conversation

alber70g
Copy link
Member

No description provided.

@imalsogreg
Copy link

Would it be good to include the Command and CommandResult types that are used to hit pact-service?

Comment on lines 157 to 160
enum ChainwebNetwork {
mainnet01
testnet04
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you want to be able to interact with test versions including devnet versions, this may be best kept as a string.

Comment on lines 162 to 165
type Cut {
height: BigInt
weight: Hash
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cuts have some more information, a cut in general is a mapping from chain IDs to block header hashes. The other properties are derived from those block headers.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For reference: the following command get a cut in JSON representation:

curl -sk https://api.chainweb.com/chainweb/0.0/mainnet01/cut | jq

Here is an example:

{
  "hashes": {
    "12": {
      "height": 3512387,
      "hash": "qoZL-lcmcixKM6DsMlGIzq4coULTjqx3Y5hfdCudJS0"
    },
    "13": {
      "height": 3512387,
      "hash": "XqnmwgX5waN3o9gWZbnsUElLNX5z1NIXLNmQtii85fc"
    },
    "14": {
      "height": 3512387,
      "hash": "XjqNxZZKGBkLVAyIofj4WsqkBaPsj_nX3HAcP9mhCSU"
    },
    "15": {
      "height": 3512387,
      "hash": "OLtNO3eaQo-0fymKsgLS9k_YCaJz9q0Tusb2m0PbDg4"
    },
    "8": {
      "height": 3512387,
      "hash": "wdMmjmYc1ykJwcSO4hahRpNsHZPFP6lyIpRcg21tMxk"
    },
    "9": {
      "height": 3512387,
      "hash": "yMPa6aYlXIDk2HGLWEv8PH1fdNwPIrbHl36r-E7YU_o"
    },
    "10": {
      "height": 3512388,
      "hash": "TC6S0S9xYoKRj6imiTfO_a3yigMFQSbcJpcHirXbmgQ"
    },
    "11": {
      "height": 3512388,
      "hash": "sbZa24LIDqeBOEYnnqRsfafd0A-JclttD9sti7mocHM"
    },
    "4": {
      "height": 3512387,
      "hash": "qfwKlsNJxPTys8MwgyXW09ynP6SXvSolrNBSRWCTW5Q"
    },
    "5": {
      "height": 3512387,
      "hash": "W88AnXR8gRfq9fLDxzmX86ixrXqkgA7dYFV4SCdAuic"
    },
    "6": {
      "height": 3512387,
      "hash": "_XYqx572X9ucwLYP5l3dDKC0IKJ9m_-2PFK0ymFtdd8"
    },
    "7": {
      "height": 3512387,
      "hash": "s4zKVxxKu0nOjoTtqZaLkaE-RV8RsV6aszdDMLHXE3g"
    },
    "0": {
      "height": 3512387,
      "hash": "HdYVc0VGaH7Su2cEDmfJuyM4Sc1Cv2S_9Jg9VKRiMOw"
    },
    "16": {
      "height": 3512386,
      "hash": "a2uzoLkEuFfsWWoPOuurvt8QeGnusnEXt0-KsnDmGMU"
    },
    "1": {
      "height": 3512387,
      "hash": "8-iv8kMTI8pC920rgnqSFlzlcEclWETR-Bfwq6tQiFI"
    },
    "17": {
      "height": 3512387,
      "hash": "uD8QPH6jWglmWp6ne6AgFNKVcPooONJgCCzMQuSlEc4"
    },
    "2": {
      "height": 3512387,
      "hash": "Um-2ceGXomt8gLFSQlIniIHDZB2_fw0Dbx5b7hE6MkA"
    },
    "18": {
      "height": 3512388,
      "hash": "SHhZ4R8f3RUfQPVPWm20P26eKgG_-UBpH9GZ_PZSXVY"
    },
    "3": {
      "height": 3512387,
      "hash": "FjirHdHhO3hOLUnkAH5f28yc7A3YjExX-ZirxDcCPfw"
    },
    "19": {
      "height": 3512387,
      "hash": "31CpGbw3ABsUxVW41SuHpIYot6eixcUB4vABk_YVwgU"
    }
  },
  "origin": null,
  "weight": "qJrdqrUWrTh-8QQAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
  "height": 70247742,
  "instance": "mainnet01",
  "id": "TSVbbu10brCcuZ_DxKbJtzYRN-UBGUndyQbgLwLYwro"
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems that the GraphQL does not support dictionaries. So there has to be a key for each chain:

Suggested change
type Cut {
height: BigInt
weight: Hash
}
type CutChain {
height: BlockHeight!
hash: BlockHash!
}
type CutHashes {
0: CutChain!
1: CutChain!
2: CutChain!
3: CutChain!
4: CutChain!
5: CutChain!
6: CutChain!
7: CutChain!
8: CutChain!
9: CutChain!
10: CutChain!
11: CutChain!
12: CutChain!
13: CutChain!
14: CutChain!
15: CutChain!
16: CutChain!
17: CutChain!
18: CutChain!
19: CutChain!
}
type Cut {
hashes: CutHashes!
origin: String
weight: BlockWeight!
height: BlockHeight!
instance: ChainwebNetwork!
id: CutHash!
}

Copy link

@larskuhtz larskuhtz Mar 3, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems that the use of numbers as keys (either directly or as string) isn't supported in GraphQL. So, the current JSON wouldn't work.

So, maybe we would have to use

type CutChain {
    chain: ChainId!
    height: BlockHeight!
    hash: BlockHash!
}

type Cut {
    hashes: [CutChain!]!
    origin: String
    weight: BlockWeight!
    height: BlockHeight!
    instance: ChainwebNetwork!
    id: CutHash!
}

This would break the existing JSON encoding.

Copy link

@larskuhtz larskuhtz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The review proposes quite a few new custom scalars. Not sure if we want that. However, the chainweb data types (Block and BlockPayload) are part of the Merkle tree and thus have pretty git types and semantics. In particular hashes are just opaque identifiers.

Recursively specified types seem to be a potential source of DOS vectors. But I don't know how queries on recursively specified types are implemented in GraphQL and whether there is a build in solution for this. Also, references to adjacent blocks form a DAG (a huge one) and if GraphQL queries aren't careful about sharing, this would result in exponential blowup in the response. So, I propose to avoid recursive types.

Also almost (but not all fields) are non-nullable.

The appropriate GraphQL representation for adjacents of a Block is an open question.

weight: Base64Url
featureFlags: Int
epochStart: MsFromPosixEpoch
adjacents: [Block]

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The use of Block makes the type recursive. Not sure if we want support this. It would probably rarely be useful and would also constitute a potential DOS vector.

Technically adjacents are a (partial) mapping from a ChainId to BlockHash. Here is an example of the JSON encoding:

"adjacents": {
    "5": "dTLm0UrocvMNjjz_TMUbWqpZhuBBht_JoNqZpCliaS8",
    "2": "fJB-vS9h7ByxNHY19WqM8icji9CcATiXn48uouHAMzs",
    "3": "UsNRCUkMKQBRDVIv0JLDfDllYNg2QO0EXaWcRfMQ6g0"
}

The problem is that the keys depend on the chain id of the block (they are the adjacent chains in the chain graph). A representation as list would assume knowledge of the graph. I don't think GraphQL's type language has support expressing this.

In GraphQL we could express this as

adjacents: [(ChainId, BlockHash)]

But this representation would break the existing JSON APIs of chainweb-node and api.chainweb.com.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure what would be a good solution. Maybe simply Object?

Or maybe using a union type for adjacents:

type Adjacents0 {
   2: BlockHash!
   3: BlockHash!
   5: BlockHash!
}
type Adjacents1 {
   # ...
}
# ...

union Adjacents = Adjacents0 | Adjacents1 | ... | Adjacents19   

Or event creating one Block type per chain? But that would be pretty verbose and would make queries more complicated.

interface Block {
    # ...
}
type Block0 implements Block { 
    adjacents: Adjacents0!
}
type Block1 {
    adjacents: Adjacents1!
}
# ...

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another problem is that the use of numbers as field keys (either directly or quoted as strings) is not supported by GraphQL. So, it is not clear how to best encode our chains. (Unfortunately, enums aren't supported as keys neither.)

target: Base64Url
nonce: Int64

payload: BlockPayload

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is should be fine, because BlockPayload is not mutually recursive with Block. Still it could allow for pretty big query results (unless restricted by other means), possibly providing a DOS vector. It is also currently not supported by chainweb-node and api.chainweb.com.

I guess, since it is not marked as nullable the server would always be free to just return null.

sig: String
}

type Block {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For reference. This returns a JSON representation of a Block:

curl -sk https://api.chainweb.com/chainweb/0.0/mainnet01/chain/0/header?limit=1 -H 'accept: application/json;blockheader-encoding=object' | jq '.items[0]'

Here is an example:

{
  "nonce": "0",
  "creationTime": 1572393660000000,
  "parent": "wJ6fVF6_vrzfemqQsWB6nCzfrMwznbZscn53-0DpAcI",
  "adjacents": {
    "5": "dTLm0UrocvMNjjz_TMUbWqpZhuBBht_JoNqZpCliaS8",
    "2": "fJB-vS9h7ByxNHY19WqM8icji9CcATiXn48uouHAMzs",
    "3": "UsNRCUkMKQBRDVIv0JLDfDllYNg2QO0EXaWcRfMQ6g0"
  },
  "target": "__________________________________________8",
  "payloadHash": "k1H3DsInAPvJ0W_zPxnrpkeSNdPUT0S9U8bqDLG739o",
  "chainId": 0,
  "weight": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
  "height": 0,
  "chainwebVersion": "mainnet01",
  "epochStart": 1572393660000000,
  "featureFlags": 0,
  "hash": "SNAMXHBvZtAbeS19x12bZV2p5d1E4BaxrggceNdUxbw"
}

Comment on lines 162 to 165
type Cut {
height: BigInt
weight: Hash
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For reference: the following command get a cut in JSON representation:

curl -sk https://api.chainweb.com/chainweb/0.0/mainnet01/cut | jq

Here is an example:

{
  "hashes": {
    "12": {
      "height": 3512387,
      "hash": "qoZL-lcmcixKM6DsMlGIzq4coULTjqx3Y5hfdCudJS0"
    },
    "13": {
      "height": 3512387,
      "hash": "XqnmwgX5waN3o9gWZbnsUElLNX5z1NIXLNmQtii85fc"
    },
    "14": {
      "height": 3512387,
      "hash": "XjqNxZZKGBkLVAyIofj4WsqkBaPsj_nX3HAcP9mhCSU"
    },
    "15": {
      "height": 3512387,
      "hash": "OLtNO3eaQo-0fymKsgLS9k_YCaJz9q0Tusb2m0PbDg4"
    },
    "8": {
      "height": 3512387,
      "hash": "wdMmjmYc1ykJwcSO4hahRpNsHZPFP6lyIpRcg21tMxk"
    },
    "9": {
      "height": 3512387,
      "hash": "yMPa6aYlXIDk2HGLWEv8PH1fdNwPIrbHl36r-E7YU_o"
    },
    "10": {
      "height": 3512388,
      "hash": "TC6S0S9xYoKRj6imiTfO_a3yigMFQSbcJpcHirXbmgQ"
    },
    "11": {
      "height": 3512388,
      "hash": "sbZa24LIDqeBOEYnnqRsfafd0A-JclttD9sti7mocHM"
    },
    "4": {
      "height": 3512387,
      "hash": "qfwKlsNJxPTys8MwgyXW09ynP6SXvSolrNBSRWCTW5Q"
    },
    "5": {
      "height": 3512387,
      "hash": "W88AnXR8gRfq9fLDxzmX86ixrXqkgA7dYFV4SCdAuic"
    },
    "6": {
      "height": 3512387,
      "hash": "_XYqx572X9ucwLYP5l3dDKC0IKJ9m_-2PFK0ymFtdd8"
    },
    "7": {
      "height": 3512387,
      "hash": "s4zKVxxKu0nOjoTtqZaLkaE-RV8RsV6aszdDMLHXE3g"
    },
    "0": {
      "height": 3512387,
      "hash": "HdYVc0VGaH7Su2cEDmfJuyM4Sc1Cv2S_9Jg9VKRiMOw"
    },
    "16": {
      "height": 3512386,
      "hash": "a2uzoLkEuFfsWWoPOuurvt8QeGnusnEXt0-KsnDmGMU"
    },
    "1": {
      "height": 3512387,
      "hash": "8-iv8kMTI8pC920rgnqSFlzlcEclWETR-Bfwq6tQiFI"
    },
    "17": {
      "height": 3512387,
      "hash": "uD8QPH6jWglmWp6ne6AgFNKVcPooONJgCCzMQuSlEc4"
    },
    "2": {
      "height": 3512387,
      "hash": "Um-2ceGXomt8gLFSQlIniIHDZB2_fw0Dbx5b7hE6MkA"
    },
    "18": {
      "height": 3512388,
      "hash": "SHhZ4R8f3RUfQPVPWm20P26eKgG_-UBpH9GZ_PZSXVY"
    },
    "3": {
      "height": 3512387,
      "hash": "FjirHdHhO3hOLUnkAH5f28yc7A3YjExX-ZirxDcCPfw"
    },
    "19": {
      "height": 3512387,
      "hash": "31CpGbw3ABsUxVW41SuHpIYot6eixcUB4vABk_YVwgU"
    }
  },
  "origin": null,
  "weight": "qJrdqrUWrTh-8QQAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
  "height": 70247742,
  "instance": "mainnet01",
  "id": "TSVbbu10brCcuZ_DxKbJtzYRN-UBGUndyQbgLwLYwro"
}

@@ -0,0 +1,165 @@
scalar Hash

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the purpose of this model hashes are most likely just unique identifiers (and possibly cryptographic fingerprints). So, it may make sense to consider them just as opaque IDs.

In any case I propose to also include the type that is referenced/identified with that hash:

Suggested change
scalar Hash
# chainweb
scalar BlockHash
scalar PayloadHash
scalar CutHash
scalar PayloadTransactionsHash
scalar PayloadOutputsHash
# pact
scalar TransactionHash

chainId: Int
weight: Base64Url
featureFlags: Int
epochStart: MsFromPosixEpoch

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
epochStart: MsFromPosixEpoch
epochStart(format: DateFormat = ISO8601): Date!

epochStart: MsFromPosixEpoch
adjacents: [Block]
payloadHash: Base64Url # fk BlockPayload
chainwebVersion: ChainwebNetwork

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
chainwebVersion: ChainwebNetwork
chainwebVersion: ChainwebNetwork!

Comment on lines 36 to 37
transactions: [Transaction] # pact realm
minerData: Account

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
transactions: [Transaction] # pact realm
minerData: Account
transactions: [Transaction!]! # pact realm
minerData: Account!

transactionsHash: Base64Url
outputsHash: Base64Url
payloadHash: Base64Url
coinbase: CoinbaseTransaction

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
coinbase: CoinbaseTransaction
coinbase: CoinbaseTransaction!

Comment on lines 89 to 90
command: TransactionCommand
commandResult: TransactionCommandResult

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some services may not have the results available (e.g. they are not needed for validation and in the future we decide to make storage of results in nodes optional). So, it probably makes sense to keep results nullable.

Suggested change
command: TransactionCommand
commandResult: TransactionCommandResult
command: TransactionCommand!
commandResult: TransactionCommandResult

@github-actions
Copy link
Contributor

This PR is stale because it is open for 60 days with no activity

@vercel
Copy link

vercel bot commented Jun 13, 2023

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
alpha-docs ✅ Ready (Inspect) Visit Preview Sep 5, 2024 9:11am
dev-wallet ✅ Ready (Inspect) Visit Preview 💬 Add feedback Sep 5, 2024 9:11am
explorer ✅ Ready (Inspect) Visit Preview 💬 Add feedback Sep 5, 2024 9:11am
kode-ui ✅ Ready (Inspect) Visit Preview 💬 Add feedback Sep 5, 2024 9:11am
marmalade-marketplace ✅ Ready (Inspect) Visit Preview 💬 Add feedback Sep 5, 2024 9:11am
proof-of-us 🛑 Canceled (Inspect) Sep 5, 2024 9:11am
react-ui ✅ Ready (Inspect) Visit Preview 💬 Add feedback Sep 5, 2024 9:11am
tools ✅ Ready (Inspect) Visit Preview 💬 Add feedback Sep 5, 2024 9:11am
2 Skipped Deployments
Name Status Preview Comments Updated (UTC)
docs-storybook ⬜️ Ignored (Inspect) Visit Preview Sep 5, 2024 9:11am
transfer ⬜️ Ignored (Inspect) Sep 5, 2024 9:11am

@github-actions
Copy link
Contributor

This PR is stale because it is open for 60 days with no activity

Copy link

changeset-bot bot commented Feb 6, 2024

⚠️ No Changeset found

Latest commit: 76fac3f

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants