Skip to content

Commit dc9cb0a

Browse files
authored
Merge pull request #5 from cloudstruct/feature/chain-sync
Chain-sync mini-protocol (part 3)
2 parents 1443725 + 4bfd3a5 commit dc9cb0a

File tree

12 files changed

+384
-69
lines changed

12 files changed

+384
-69
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,6 @@
1414

1515
# Dependency directories (remove the comment below to include it)
1616
# vendor/
17+
18+
# Temporary dir for testing
19+
/tmp/

README.md

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,53 @@ but the node-to-node protocols will also be implemented in time.
2424
| Local State Query | Not Implemented |
2525
| Keep-Alive | Not Implemented |
2626

27+
## Testing
28+
29+
Testing is currently a mostly manual process. There's an included test program that use the library
30+
and a Docker Compose file to launch a local `cardano-node` instance.
31+
32+
### Starting the local `cardano-node` instance
33+
34+
```
35+
$ docker-compose up -d
36+
```
37+
38+
If you want to use `mainnet`, set the `CARDANO_NETWORK` environment variable.
39+
40+
```
41+
$ export CARDANO_NETWORK=mainnet
42+
$ docker-compose up -d
43+
```
44+
45+
You can communicate with the `cardano-node` instance on port `8081` (for "public" node-to-node protocol), port `8082` (for "private" node-to-client protocol), or
46+
the `./tmp/cardano-node/ipc/node.socket` UNIX socket file (also for "private" node-to-client protocol).
47+
48+
NOTE: if using the UNIX socket file, you may need to adjust the permissions/ownership to allow your user to access it.
49+
The `cardano-node` Docker image runs as `root` by default and the UNIX socket ends up with `root:root` ownership
50+
and `0755` permissions, which doesn't allow a non-root use to write to it by default.
51+
52+
### Running `cardano-cli` against local `cardano-node` instance
53+
54+
```
55+
$ docker exec -ti go-ouroboros-network_cardano-node_1 sh -c 'CARDANO_NODE_SOCKET_PATH=/ipc/node.socket cardano-cli query tip --testnet-magic 1097911063'
56+
```
57+
58+
### Building and running the test program
59+
60+
Compile the test program.
61+
62+
```
63+
$ make
64+
```
65+
66+
Run the test program pointing to the UNIX socket from the `cardano-node` instance started above.
67+
68+
```
69+
$ ./go-ouroboros-network -address localhost:8082 -testnet
70+
```
71+
72+
### Stopping the local `cardano-node` instance
73+
74+
```
75+
$ docker-compose down --volumes
76+
```

block/allegra.go

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,26 @@
11
package block
22

3+
import (
4+
"github.com/fxamacker/cbor/v2"
5+
)
6+
37
const (
4-
BLOCK_TYPE_ALLEGRA = 4
8+
BLOCK_TYPE_ALLEGRA = 3
59
)
10+
11+
type AllegraBlock struct {
12+
// Tells the CBOR decoder to convert to/from a struct and a CBOR array
13+
_ struct{} `cbor:",toarray"`
14+
Header ShelleyBlockHeader
15+
TransactionBodies []AllegraTransaction
16+
TransactionWitnessSets []ShelleyTransactionWitnessSet
17+
// TODO: figure out how to parse properly
18+
// We use RawMessage here because the content is arbitrary and can contain data that
19+
// cannot easily be represented in Go (such as maps with bytestring keys)
20+
TransactionMetadataSet map[uint]cbor.RawMessage
21+
}
22+
23+
type AllegraTransaction struct {
24+
ShelleyTransaction
25+
ValidityIntervalStart uint64 `cbor:"8,keyasint,omitempty"`
26+
}

block/alonzo.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,40 @@
11
package block
22

3+
import (
4+
"github.com/fxamacker/cbor/v2"
5+
)
6+
37
const (
48
BLOCK_TYPE_ALONZO = 5
59
)
10+
11+
type AlonzoBlock struct {
12+
// Tells the CBOR decoder to convert to/from a struct and a CBOR array
13+
_ struct{} `cbor:",toarray"`
14+
Header ShelleyBlockHeader
15+
TransactionBodies []AlonzoTransaction
16+
TransactionWitnessSets []AlonzoTransactionWitnessSet
17+
// TODO: figure out how to parse properly
18+
// We use RawMessage here because the content is arbitrary and can contain data that
19+
// cannot easily be represented in Go (such as maps with bytestring keys)
20+
TransactionMetadataSet map[uint]cbor.RawMessage
21+
InvalidTransactions []uint
22+
}
23+
24+
type AlonzoTransaction struct {
25+
MaryTransaction
26+
ScriptDataHash Blake2b256 `cbor:"11,keyasint,omitempty"`
27+
Collateral []ShelleyTransactionInput `cbor:"13,keyasint,omitempty"`
28+
RequiredSigners []Blake2b224 `cbor:"14,keyasint,omitempty"`
29+
NetworkId uint8 `cbor:"15,keyasint,omitempty"`
30+
}
31+
32+
type AlonzoTransactionWitnessSet struct {
33+
ShelleyTransactionWitnessSet
34+
PlutusScripts interface{} `cbor:"3,keyasint,omitempty"`
35+
// TODO: figure out how to parse properly
36+
// We use RawMessage here because the content is arbitrary and can contain data that
37+
// cannot easily be represented in Go (such as maps with bytestring keys)
38+
PlutusData []cbor.RawMessage `cbor:"4,keyasint,omitempty"`
39+
Redeemers []cbor.RawMessage `cbor:"5,keyasint,omitempty"`
40+
}

block/bryon.go

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
package block
22

3+
import (
4+
"github.com/fxamacker/cbor/v2"
5+
)
6+
37
const (
48
BLOCK_TYPE_BYRON_EBB = 0
59
BLOCK_TYPE_BYRON_MAIN = 1
@@ -52,9 +56,11 @@ type ByronMainBlockHeader struct {
5256

5357
type ByronMainBlockBody struct {
5458
// Tells the CBOR decoder to convert to/from a struct and a CBOR array
55-
_ struct{} `cbor:",toarray"`
56-
TxPayload []interface{}
57-
SscPayload *BlockBodySscPayload
59+
_ struct{} `cbor:",toarray"`
60+
TxPayload []interface{}
61+
// We keep this field as raw CBOR, since it contains a map with []byte
62+
// keys, which Go doesn't allow
63+
SscPayload cbor.RawMessage
5864
DlgPayload []interface{}
5965
UpdPayload []interface{}
6066
}
@@ -69,15 +75,6 @@ type ByronEpochBoundaryBlockHeader struct {
6975
ExtraData interface{}
7076
}
7177

72-
// This mostly exists to override the below function
73-
type BlockBodySscPayload struct{}
74-
75-
// Prevent unmarshaling of the SSC payload data, since it contains a map with
76-
// []byte keys, which Go doesn't allow
77-
func (payload *BlockBodySscPayload) UnmarshalCBOR(data []byte) error {
78-
return nil
79-
}
80-
8178
type ByronMainBlock struct {
8279
// Tells the CBOR decoder to convert to/from a struct and a CBOR array
8380
_ struct{} `cbor:",toarray"`

block/mary.go

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,39 @@
11
package block
22

3+
import (
4+
// "fmt"
5+
"github.com/fxamacker/cbor/v2"
6+
)
7+
38
const (
4-
BLOCK_TYPE_MARY = 3
9+
BLOCK_TYPE_MARY = 4
510
)
11+
12+
type MaryBlock struct {
13+
// Tells the CBOR decoder to convert to/from a struct and a CBOR array
14+
_ struct{} `cbor:",toarray"`
15+
Header ShelleyBlockHeader
16+
TransactionBodies []MaryTransaction
17+
TransactionWitnessSets []ShelleyTransactionWitnessSet
18+
// TODO: figure out how to parse properly
19+
// We use RawMessage here because the content is arbitrary and can contain data that
20+
// cannot easily be represented in Go (such as maps with bytestring keys)
21+
TransactionMetadataSet map[uint]cbor.RawMessage
22+
}
23+
24+
type MaryTransaction struct {
25+
AllegraTransaction
26+
//Outputs []MaryTransactionOutput `cbor:"1,keyasint,omitempty"`
27+
Outputs []cbor.RawMessage `cbor:"1,keyasint,omitempty"`
28+
// TODO: further parsing of this field
29+
Mint cbor.RawMessage `cbor:"9,keyasint,omitempty"`
30+
}
31+
32+
// TODO: support both forms
33+
/*
34+
transaction_output = [address, amount : value]
35+
value = coin / [coin,multiasset<uint>]
36+
*/
37+
//type MaryTransactionOutput interface{}
38+
39+
type MaryTransactionOutput cbor.RawMessage

block/shelley.go

Lines changed: 67 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -10,36 +10,80 @@ const (
1010

1111
type ShelleyBlock struct {
1212
// Tells the CBOR decoder to convert to/from a struct and a CBOR array
13-
_ struct{} `cbor:",toarray"`
14-
Header ShelleyBlockHeader
15-
// TODO: create structure for transaction bodies that accounts for
16-
// map with bytestring keys for staking reward withdrawals
17-
TransactionBodies []cbor.RawMessage
18-
TransactionWitnessSets interface{}
19-
TransactionMetadataSet interface{}
13+
_ struct{} `cbor:",toarray"`
14+
Header ShelleyBlockHeader
15+
TransactionBodies []ShelleyTransaction
16+
TransactionWitnessSets []ShelleyTransactionWitnessSet
17+
// TODO: figure out how to parse properly
18+
// We use RawMessage here because the content is arbitrary and can contain data that
19+
// cannot easily be represented in Go (such as maps with bytestring keys)
20+
TransactionMetadataSet map[uint]cbor.RawMessage
2021
}
2122

2223
type ShelleyBlockHeader struct {
2324
// Tells the CBOR decoder to convert to/from a struct and a CBOR array
2425
_ struct{} `cbor:",toarray"`
2526
Body struct {
2627
// Tells the CBOR decoder to convert to/from a struct and a CBOR array
27-
_ struct{} `cbor:",toarray"`
28-
BlockNumber uint64
29-
Slot uint64
30-
PrevHash Blake2b256
31-
IssuerVkey interface{}
32-
VrfKey interface{}
33-
NonceVrf interface{}
34-
LeaderVrf interface{}
35-
BlockBodySize uint32
36-
BlockBodyHash Blake2b256
37-
HotVkey interface{}
38-
SequenceNumber uint32
39-
KesPeriod uint32
40-
Sigma interface{}
41-
OperationalCertNum uint
42-
ProtocolVersion interface{}
28+
_ struct{} `cbor:",toarray"`
29+
BlockNumber uint64
30+
Slot uint64
31+
PrevHash Blake2b256
32+
IssuerVkey interface{}
33+
VrfKey interface{}
34+
NonceVrf interface{}
35+
LeaderVrf interface{}
36+
BlockBodySize uint32
37+
BlockBodyHash Blake2b256
38+
OpCertHotVkey interface{}
39+
OpCertSequenceNumber uint32
40+
OpCertKesPeriod uint32
41+
OpCertSignature interface{}
42+
ProtoMajorVersion uint64
43+
ProtoMinorVersion uint64
4344
}
4445
Signature interface{}
4546
}
47+
48+
type ShelleyTransaction struct {
49+
Inputs []ShelleyTransactionInput `cbor:"0,keyasint,omitempty"`
50+
Outputs []ShelleyTransactionOutput `cbor:"1,keyasint,omitempty"`
51+
Fee uint64 `cbor:"2,keyasint,omitempty"`
52+
Ttl uint64 `cbor:"3,keyasint,omitempty"`
53+
// TODO: figure out how to parse properly
54+
Certificates []cbor.RawMessage `cbor:"4,keyasint,omitempty"`
55+
// TODO: figure out how to parse this correctly
56+
// We keep the raw CBOR because it can contain a map with []byte keys, which
57+
// Go does not allow
58+
Withdrawals cbor.RawMessage `cbor:"5,keyasint,omitempty"`
59+
Update struct {
60+
// Tells the CBOR decoder to convert to/from a struct and a CBOR array
61+
_ struct{} `cbor:",toarray"`
62+
// TODO: figure out how to parse properly
63+
// We use RawMessage here because the content is arbitrary and can contain data that
64+
// cannot easily be represented in Go (such as maps with bytestring keys)
65+
ProtocolParamUpdates cbor.RawMessage
66+
Epoch uint64
67+
} `cbor:"6,keyasint,omitempty"`
68+
MetadataHash Blake2b256 `cbor:"7,keyasint,omitempty"`
69+
}
70+
71+
type ShelleyTransactionInput struct {
72+
// Tells the CBOR decoder to convert to/from a struct and a CBOR array
73+
_ struct{} `cbor:",toarray"`
74+
Id Blake2b256
75+
Index uint32
76+
}
77+
78+
type ShelleyTransactionOutput struct {
79+
// Tells the CBOR decoder to convert to/from a struct and a CBOR array
80+
_ struct{} `cbor:",toarray"`
81+
Address Blake2b256
82+
Amount uint64
83+
}
84+
85+
type ShelleyTransactionWitnessSet struct {
86+
VkeyWitnesses []interface{} `cbor:"0,keyasint,omitempty"`
87+
MultisigScripts []interface{} `cbor:"1,keyasint,omitempty"`
88+
BootstrapWitnesses []interface{} `cbor:"2,keyasint,omitempty"`
89+
}

0 commit comments

Comments
 (0)