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

API v2 specification along with the new requirements #300

Closed
wants to merge 43 commits into from
Closed
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
3b736eb
Add Account and Transaction service
kacpersaw Dec 22, 2023
063c964
Add v2 resources according to specification (account, block, layer, r…
kacpersaw Jan 5, 2024
090594f
Add v2 transaction service
kacpersaw Jan 18, 2024
2485b17
Update spacemesh/v2/account.proto
kacpersaw Feb 2, 2024
f4b4a86
Update spacemesh/v2/block.proto
kacpersaw Feb 2, 2024
7145b78
Update spacemesh/v2/layer.proto
kacpersaw Feb 2, 2024
2dd0cd8
Apply suggestions from code review
kacpersaw Feb 2, 2024
c3aca8c
Apply suggestions from review comments
kacpersaw Feb 2, 2024
cc61f8e
Add comments
kacpersaw Feb 5, 2024
4217e64
remove bitfield from nonce type
kacpersaw Feb 5, 2024
bcf10c5
add ParseTransactionResponse
kacpersaw Feb 5, 2024
0ea7633
return tx_id for submitted tx
kacpersaw Feb 5, 2024
babbcee
Add ListBySmesher to RewardService
kacpersaw Feb 5, 2024
39e5d8f
Add EstimateGas to TransactionService
kacpersaw Feb 6, 2024
8bf4fdb
Fix rewards and build v2
kacpersaw Feb 6, 2024
56cef0b
Add parsed tx contents
lrettig Feb 15, 2024
44131e9
Update spacemesh/v2/network.proto
kacpersaw Feb 16, 2024
356967c
Update spacemesh/v2/network.proto
kacpersaw Feb 16, 2024
ec026ea
Move v2 to v2alpha1
kacpersaw Feb 16, 2024
24b2b30
Remove layer limits
kacpersaw Feb 16, 2024
3fef9a1
Apply review suggestions
kacpersaw Feb 16, 2024
1a4b69a
buf generate
kacpersaw Feb 16, 2024
f42ab30
Rename head_block
kacpersaw Feb 20, 2024
47d1c76
Bump google.golang.org/protobuf from 1.31.0 to 1.32.0 in /release/go
dependabot[bot] Dec 22, 2023
7698cda
Bump github.com/grpc-ecosystem/grpc-gateway/v2 in /release/go
dependabot[bot] Jan 4, 2024
3a80bb0
Add "until" to PoetWaitRound, PoetWaitProof, AtxPublished events
xearl4 Jan 10, 2024
2d8ac12
Fix indentation
xearl4 Dec 29, 2023
4b804d4
Bump google.golang.org/grpc from 1.60.1 to 1.61.0 in /release/go
dependabot[bot] Jan 24, 2024
a316deb
Bump github.com/grpc-ecosystem/grpc-gateway/v2 in /release/go
dependabot[bot] Jan 30, 2024
28f69e2
Add POST_INDEX malfeasance proof
poszu Jan 12, 2024
1a80a40
Extend API for multismesher node
fasmat Jan 31, 2024
d2c765a
Add v2alpha1 atxs
kacpersaw Feb 14, 2024
d5f6f85
Apply suggestions from review
kacpersaw Feb 14, 2024
88b67dc
Update build
kacpersaw Feb 14, 2024
5df3172
Update spacemesh/v2alpha1/activation.proto
kacpersaw Feb 14, 2024
194553a
Modify comment
kacpersaw Feb 14, 2024
c2aee87
Modify comment
kacpersaw Feb 14, 2024
5c8fe0f
generate new build
kacpersaw Feb 14, 2024
0d45302
Bump google.golang.org/grpc from 1.61.0 to 1.61.1 in /release/go
dependabot[bot] Feb 14, 2024
52e1aa5
switch reward smesher field to bytes
kacpersaw Feb 20, 2024
47f0e8a
Add layer filter to reward request
kacpersaw Feb 20, 2024
71210bf
Add start/end layer filter to reward request
kacpersaw Feb 20, 2024
ef8ca21
Add reward stream service
kacpersaw Feb 20, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
28 changes: 28 additions & 0 deletions spacemesh/v2/account.proto
@@ -0,0 +1,28 @@
syntax = "proto3";

package spacemesh.v2;

message Account {
oneof versioned {
AccountV1 v1 = 1;
}
}

message AccountV1 {
string account_id = 1; // account public address
AccountState state_current = 2; // current state
AccountState state_projected = 3; // projected state (includes pending txs)
}

message AccountState {
kacpersaw marked this conversation as resolved.
Show resolved Hide resolved
uint64 counter = 1; // aka nonce
uint64 balance = 2; // known account balance
kacpersaw marked this conversation as resolved.
Show resolved Hide resolved
}

message AccountRequest {
string address = 1;
kacpersaw marked this conversation as resolved.
Show resolved Hide resolved
};

service AccountService {
rpc Get(AccountRequest) returns (Account);
}
26 changes: 26 additions & 0 deletions spacemesh/v2/block.proto
@@ -0,0 +1,26 @@
syntax = "proto3";

import "spacemesh/v2/tx.proto";

package spacemesh.v2;

message Block {
oneof versioned {
BlockV1 v1 = 1;
}
}

message BlockV1 {
Copy link
Member

Choose a reason for hiding this comment

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

I think we need to split block into block header and full block. Header includes a list of TXIDs, but not full transactions.

Copy link
Contributor Author

@kacpersaw kacpersaw Feb 5, 2024

Choose a reason for hiding this comment

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

In v1, full transactions are sent within a block. I'm not sure if we want to change that. What do you think?

bytes id = 1; // block hash
repeated Transaction transactions = 2; // block transactions
kacpersaw marked this conversation as resolved.
Show resolved Hide resolved
bytes activation_id = 3; // the smesher's activation that this block refers to
kacpersaw marked this conversation as resolved.
Show resolved Hide resolved
bytes smesher_id = 4; // the id of the smesher who submitted this block
}

message BlockRequest {
bytes id = 1; // block hash
}

service BlockService {
kacpersaw marked this conversation as resolved.
Show resolved Hide resolved
rpc Get(BlockRequest) returns (Block);
}
35 changes: 35 additions & 0 deletions spacemesh/v2/layer.proto
@@ -0,0 +1,35 @@
syntax = "proto3";

import "spacemesh/v2/block.proto";

package spacemesh.v2;

message Layer {
oneof versioned {
BlockV1 v1 = 1;
}
}

message LayerV1 {
Copy link
Member

Choose a reason for hiding this comment

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

it seems like this data structure is actually unused in this design, since Layer contains only a block. this should be fixed.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

What about hash and root_state_hash?

uint32 number = 1; // layer number - not hash - layer content may change
enum LayerStatus {
LAYER_STATUS_UNSPECIFIED = 0; // not yet approved or confirmed
LAYER_STATUS_APPROVED = 1; // approved by hare
LAYER_STATUS_CONFIRMED = 2; // confirmed by tortoise
LAYER_STATUS_APPLIED = 3; // applied in state
kacpersaw marked this conversation as resolved.
Show resolved Hide resolved
}
LayerStatus status = 2;
bytes hash = 3; // computer layer hash - do we need this?
repeated Block blocks = 4; // layer's blocks
kacpersaw marked this conversation as resolved.
Show resolved Hide resolved
bytes root_state_hash = 5; // when available - the root state hash of global state in this layer
kacpersaw marked this conversation as resolved.
Show resolved Hide resolved
}

message LayerRequest {
uint32 layer_number = 1;
bool include_transactions = 2;
};


service LayerService {
rpc Get(LayerRequest) returns (Layer);
}
20 changes: 20 additions & 0 deletions spacemesh/v2/network.proto
@@ -0,0 +1,20 @@
syntax = "proto3";

package spacemesh.v2;

message NetworkInfoRequest {}

message NetworkInfoResponse {
uint64 genesis_time = 1; // network genesis time as unix epoch time
kacpersaw marked this conversation as resolved.
Show resolved Hide resolved
uint32 epoch_num_layers = 2; // number of layers per epoch
uint64 layer_duration = 3; // layer duration, in seconds
kacpersaw marked this conversation as resolved.
Show resolved Hide resolved
uint64 max_transactions_per_second = 4;
kacpersaw marked this conversation as resolved.
Show resolved Hide resolved
string hrp = 5;
uint32 first_genesis = 6;
lrettig marked this conversation as resolved.
Show resolved Hide resolved
uint32 effective_genesis = 7;
uint32 epoch_size = 8;
lrettig marked this conversation as resolved.
Show resolved Hide resolved
}

service NetworkService {
rpc Info(NetworkInfoRequest) returns (NetworkInfoResponse);
}
18 changes: 18 additions & 0 deletions spacemesh/v2/node.proto
@@ -0,0 +1,18 @@
syntax = "proto3";

package spacemesh.v2;

message NodeStatusRequest {}

message NodeStatusResponse {
uint64 connected_peers = 1; // number of connected neighbors
bool is_synced = 2; // true when meshed is synced
kacpersaw marked this conversation as resolved.
Show resolved Hide resolved
uint32 synced_layer = 3; // the last layer node has synced
uint32 verified_layer = 4; // the last layer node has verified
uint32 head_layer = 5; // head layer is the tip
lrettig marked this conversation as resolved.
Show resolved Hide resolved
uint32 head_block = 6;
Copy link
Member

Choose a reason for hiding this comment

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

I think we need to add something like current_layer which is the current layer number based strictly on time

Copy link
Contributor Author

Choose a reason for hiding this comment

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

in v1 we have

synced_layer - latest layer we saw from the network
top_layer - current layer, based on time
verified_layer - latest verified layer

what is your proposal?

Copy link
Member

Choose a reason for hiding this comment

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

I think we're missing one. Here's my proposal:

  uint32 synced_layer = 3; // last layer node has synced
  uint32 verified_layer = 4; // last layer node has verified
  uint32 head_layer = 5; // current chain head; the last layer the node has gossiped or seen
  uint32 current_layer = 6; // current layer, based on clock time

synced_layer is only useful while syncing. Blocks are also received via gossip. The relationship should be:

synced_layer <= verified_layer <= head_layer <= current_layer

}

service NodeService {
rpc Status(NodeStatusRequest) returns (NodeStatusResponse);
}
32 changes: 32 additions & 0 deletions spacemesh/v2/reward.proto
@@ -0,0 +1,32 @@
syntax = "proto3";

package spacemesh.v2;

message Reward {
oneof versioned {
RewardV1 v1 = 1;
}
}

message RewardV1 {
uint32 layer = 1; // layer award was paid in
uint64 total = 2; // total reward paid (sum of tx fee and layer reward)
kacpersaw marked this conversation as resolved.
Show resolved Hide resolved
uint64 layer_reward = 3; // tx_fee = total - layer_reward
uint32 layer_computed = 4; // layer number of the layer when reward was computed
kacpersaw marked this conversation as resolved.
Show resolved Hide resolved
string coinbase = 5; // account awarded this reward
bytes smesher = 6; // id of smesher who earned this reward
kacpersaw marked this conversation as resolved.
Show resolved Hide resolved
}

message RewardRequest {
kacpersaw marked this conversation as resolved.
Show resolved Hide resolved
string coinbase = 1;
uint64 offset = 2;
kacpersaw marked this conversation as resolved.
Show resolved Hide resolved
uint64 limit = 3;
}

message RewardList {
repeated Reward rewards = 1;
}

service RewardService {
rpc List(RewardRequest) returns (RewardList);
}
114 changes: 114 additions & 0 deletions spacemesh/v2/tx.proto
@@ -0,0 +1,114 @@
syntax = "proto3";

import "google/rpc/status.proto";

package spacemesh.v2;

message Transaction {
oneof versioned {
TransactionV1 v1 = 1;
}
}

// An immutable Spacemesh transaction.
// do not include mutable data such as tx state or result.
message TransactionV1 {
kacpersaw marked this conversation as resolved.
Show resolved Hide resolved
Copy link
Member

Choose a reason for hiding this comment

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

need to also add recipient and send amount (for Send txs). I'm not 100% sure how to structure this. we should probably add a subfield, something liked ParsedContents, that's oneof depending on the type of tx (spawn, self spawn, send, etc.)

Copy link
Contributor Author

@kacpersaw kacpersaw Feb 5, 2024

Choose a reason for hiding this comment

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

we can also left that to user. In explorer I'm parsing every tx from raw format, but if you want to put everything as fields we can do that.

Copy link
Member

Choose a reason for hiding this comment

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

Yes, this is an important requirement for consumers. We shouldn't require them to parse a raw TX, the API should provide the parsed TX. If for some reason we think this will be expensive, we can add a flag to the Request object to enable this.

bytes id = 1;
string principal = 2;
kacpersaw marked this conversation as resolved.
Show resolved Hide resolved
string template = 3;
kacpersaw marked this conversation as resolved.
Show resolved Hide resolved
uint32 method = 4; // this is actually limited by uint8, but no type for that.
Nonce nonce = 5;
LayerLimits limits = 6;
Copy link
Member

Choose a reason for hiding this comment

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

need to double check but pretty sure this is unused, not sure we want to include this

Copy link
Member

Choose a reason for hiding this comment

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

confirmed, layer limits for tx are not currently enabled. let's remove this for now for simplicity and to avoid confusion.

uint64 max_gas = 7;
kacpersaw marked this conversation as resolved.
Show resolved Hide resolved
uint64 gas_price = 8;
kacpersaw marked this conversation as resolved.
Show resolved Hide resolved
uint64 max_spend = 9;
bytes raw = 10;
}

message Nonce {
uint64 counter = 1;
uint32 bitfield = 2; // this is actually limited by uint8, but no type for that.
kacpersaw marked this conversation as resolved.
Show resolved Hide resolved
}

message LayerLimits {
uint32 min = 1;
uint32 max = 2;
}

// TransactionState is the "journey" of a tx from mempool to block inclusion to
// mesh to STF processing. To know whether or not the tx actually succeeded,
// and its side effects, check the Receipt in the GlobalStateService.
message TransactionState {
bytes id = 1;
enum TransactionState {
TRANSACTION_STATE_UNSPECIFIED = 0; // default state
TRANSACTION_STATE_REJECTED = 1; // rejected from mempool due to, e.g., invalid syntax
TRANSACTION_STATE_INSUFFICIENT_FUNDS = 2; // rejected from mempool by funds check
TRANSACTION_STATE_CONFLICTING = 3; // rejected from mempool due to conflicting counter
TRANSACTION_STATE_MEMPOOL = 4; // in mempool but not on the mesh yet
TRANSACTION_STATE_MESH = 5; // submitted to the mesh
TRANSACTION_STATE_PROCESSED = 6; // processed by STF; check Receipt for success or failure
}
TransactionState state = 2;
}

message TransactionResult {
enum Status {
SUCCESS = 0;
FAILURE = 1;
INVALID = 2;
}

Transaction tx = 1;
Status status = 2;
string message = 3;
uint64 gas_consumed = 4;
kacpersaw marked this conversation as resolved.
Show resolved Hide resolved
uint64 fee = 5;
kacpersaw marked this conversation as resolved.
Show resolved Hide resolved
bytes block = 6;
uint32 layer = 7;
repeated string touched_addresses = 8;
lrettig marked this conversation as resolved.
Show resolved Hide resolved
}

message TransactionStreamRequest {
uint32 start_layer = 1;
uint32 end_layer = 2;
bytes id = 3;
string address = 4;
bool watch = 5;
}

service TransactionStreamService {
rpc Stream(TransactionStreamRequest) returns (stream Transaction);
}

message TransactionRequest {
bytes id = 1;
bool include_state = 2;
bool include_result = 3;
}

message TransactionResponse {
Transaction tx = 1;
TransactionState tx_state = 2;
TransactionResult tx_result = 3;
}

message ParseTransactionRequest {
bytes transaction = 1; // signed binary transaction
bool verify = 2; // if true signature verification will be executed
}

message SubmitTransactionRequest {
bytes transaction = 1; // signed binary transaction
}

message SubmitTransactionResponse {
kacpersaw marked this conversation as resolved.
Show resolved Hide resolved
google.rpc.Status status = 1;
TransactionState tx_state = 2;
}

service TransactionService {
rpc Get(TransactionRequest) returns (TransactionResponse);
rpc ParseTransaction(ParseTransactionRequest) returns (ParseTransactionRequest);
kacpersaw marked this conversation as resolved.
Show resolved Hide resolved
rpc SubmitTransaction(SubmitTransactionRequest) returns (SubmitTransactionResponse);
}