Skip to content

Commit

Permalink
Merge pull request #5 from cloudstruct/feature/chain-sync
Browse files Browse the repository at this point in the history
Chain-sync mini-protocol (part 3)
  • Loading branch information
agaffney authored Jan 20, 2022
2 parents 1443725 + 4bfd3a5 commit dc9cb0a
Show file tree
Hide file tree
Showing 12 changed files with 384 additions and 69 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,6 @@

# Dependency directories (remove the comment below to include it)
# vendor/

# Temporary dir for testing
/tmp/
50 changes: 50 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,53 @@ but the node-to-node protocols will also be implemented in time.
| Local State Query | Not Implemented |
| Keep-Alive | Not Implemented |

## Testing

Testing is currently a mostly manual process. There's an included test program that use the library
and a Docker Compose file to launch a local `cardano-node` instance.

### Starting the local `cardano-node` instance

```
$ docker-compose up -d
```

If you want to use `mainnet`, set the `CARDANO_NETWORK` environment variable.

```
$ export CARDANO_NETWORK=mainnet
$ docker-compose up -d
```

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
the `./tmp/cardano-node/ipc/node.socket` UNIX socket file (also for "private" node-to-client protocol).

NOTE: if using the UNIX socket file, you may need to adjust the permissions/ownership to allow your user to access it.
The `cardano-node` Docker image runs as `root` by default and the UNIX socket ends up with `root:root` ownership
and `0755` permissions, which doesn't allow a non-root use to write to it by default.

### Running `cardano-cli` against local `cardano-node` instance

```
$ 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'
```

### Building and running the test program

Compile the test program.

```
$ make
```

Run the test program pointing to the UNIX socket from the `cardano-node` instance started above.

```
$ ./go-ouroboros-network -address localhost:8082 -testnet
```

### Stopping the local `cardano-node` instance

```
$ docker-compose down --volumes
```
23 changes: 22 additions & 1 deletion block/allegra.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,26 @@
package block

import (
"github.com/fxamacker/cbor/v2"
)

const (
BLOCK_TYPE_ALLEGRA = 4
BLOCK_TYPE_ALLEGRA = 3
)

type AllegraBlock struct {
// Tells the CBOR decoder to convert to/from a struct and a CBOR array
_ struct{} `cbor:",toarray"`
Header ShelleyBlockHeader
TransactionBodies []AllegraTransaction
TransactionWitnessSets []ShelleyTransactionWitnessSet
// TODO: figure out how to parse properly
// We use RawMessage here because the content is arbitrary and can contain data that
// cannot easily be represented in Go (such as maps with bytestring keys)
TransactionMetadataSet map[uint]cbor.RawMessage
}

type AllegraTransaction struct {
ShelleyTransaction
ValidityIntervalStart uint64 `cbor:"8,keyasint,omitempty"`
}
35 changes: 35 additions & 0 deletions block/alonzo.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,40 @@
package block

import (
"github.com/fxamacker/cbor/v2"
)

const (
BLOCK_TYPE_ALONZO = 5
)

type AlonzoBlock struct {
// Tells the CBOR decoder to convert to/from a struct and a CBOR array
_ struct{} `cbor:",toarray"`
Header ShelleyBlockHeader
TransactionBodies []AlonzoTransaction
TransactionWitnessSets []AlonzoTransactionWitnessSet
// TODO: figure out how to parse properly
// We use RawMessage here because the content is arbitrary and can contain data that
// cannot easily be represented in Go (such as maps with bytestring keys)
TransactionMetadataSet map[uint]cbor.RawMessage
InvalidTransactions []uint
}

type AlonzoTransaction struct {
MaryTransaction
ScriptDataHash Blake2b256 `cbor:"11,keyasint,omitempty"`
Collateral []ShelleyTransactionInput `cbor:"13,keyasint,omitempty"`
RequiredSigners []Blake2b224 `cbor:"14,keyasint,omitempty"`
NetworkId uint8 `cbor:"15,keyasint,omitempty"`
}

type AlonzoTransactionWitnessSet struct {
ShelleyTransactionWitnessSet
PlutusScripts interface{} `cbor:"3,keyasint,omitempty"`
// TODO: figure out how to parse properly
// We use RawMessage here because the content is arbitrary and can contain data that
// cannot easily be represented in Go (such as maps with bytestring keys)
PlutusData []cbor.RawMessage `cbor:"4,keyasint,omitempty"`
Redeemers []cbor.RawMessage `cbor:"5,keyasint,omitempty"`
}
21 changes: 9 additions & 12 deletions block/bryon.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
package block

import (
"github.com/fxamacker/cbor/v2"
)

const (
BLOCK_TYPE_BYRON_EBB = 0
BLOCK_TYPE_BYRON_MAIN = 1
Expand Down Expand Up @@ -52,9 +56,11 @@ type ByronMainBlockHeader struct {

type ByronMainBlockBody struct {
// Tells the CBOR decoder to convert to/from a struct and a CBOR array
_ struct{} `cbor:",toarray"`
TxPayload []interface{}
SscPayload *BlockBodySscPayload
_ struct{} `cbor:",toarray"`
TxPayload []interface{}
// We keep this field as raw CBOR, since it contains a map with []byte
// keys, which Go doesn't allow
SscPayload cbor.RawMessage
DlgPayload []interface{}
UpdPayload []interface{}
}
Expand All @@ -69,15 +75,6 @@ type ByronEpochBoundaryBlockHeader struct {
ExtraData interface{}
}

// This mostly exists to override the below function
type BlockBodySscPayload struct{}

// Prevent unmarshaling of the SSC payload data, since it contains a map with
// []byte keys, which Go doesn't allow
func (payload *BlockBodySscPayload) UnmarshalCBOR(data []byte) error {
return nil
}

type ByronMainBlock struct {
// Tells the CBOR decoder to convert to/from a struct and a CBOR array
_ struct{} `cbor:",toarray"`
Expand Down
36 changes: 35 additions & 1 deletion block/mary.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,39 @@
package block

import (
// "fmt"
"github.com/fxamacker/cbor/v2"
)

const (
BLOCK_TYPE_MARY = 3
BLOCK_TYPE_MARY = 4
)

type MaryBlock struct {
// Tells the CBOR decoder to convert to/from a struct and a CBOR array
_ struct{} `cbor:",toarray"`
Header ShelleyBlockHeader
TransactionBodies []MaryTransaction
TransactionWitnessSets []ShelleyTransactionWitnessSet
// TODO: figure out how to parse properly
// We use RawMessage here because the content is arbitrary and can contain data that
// cannot easily be represented in Go (such as maps with bytestring keys)
TransactionMetadataSet map[uint]cbor.RawMessage
}

type MaryTransaction struct {
AllegraTransaction
//Outputs []MaryTransactionOutput `cbor:"1,keyasint,omitempty"`
Outputs []cbor.RawMessage `cbor:"1,keyasint,omitempty"`
// TODO: further parsing of this field
Mint cbor.RawMessage `cbor:"9,keyasint,omitempty"`
}

// TODO: support both forms
/*
transaction_output = [address, amount : value]
value = coin / [coin,multiasset<uint>]
*/
//type MaryTransactionOutput interface{}

type MaryTransactionOutput cbor.RawMessage
90 changes: 67 additions & 23 deletions block/shelley.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,36 +10,80 @@ const (

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

type ShelleyBlockHeader struct {
// Tells the CBOR decoder to convert to/from a struct and a CBOR array
_ struct{} `cbor:",toarray"`
Body struct {
// Tells the CBOR decoder to convert to/from a struct and a CBOR array
_ struct{} `cbor:",toarray"`
BlockNumber uint64
Slot uint64
PrevHash Blake2b256
IssuerVkey interface{}
VrfKey interface{}
NonceVrf interface{}
LeaderVrf interface{}
BlockBodySize uint32
BlockBodyHash Blake2b256
HotVkey interface{}
SequenceNumber uint32
KesPeriod uint32
Sigma interface{}
OperationalCertNum uint
ProtocolVersion interface{}
_ struct{} `cbor:",toarray"`
BlockNumber uint64
Slot uint64
PrevHash Blake2b256
IssuerVkey interface{}
VrfKey interface{}
NonceVrf interface{}
LeaderVrf interface{}
BlockBodySize uint32
BlockBodyHash Blake2b256
OpCertHotVkey interface{}
OpCertSequenceNumber uint32
OpCertKesPeriod uint32
OpCertSignature interface{}
ProtoMajorVersion uint64
ProtoMinorVersion uint64
}
Signature interface{}
}

type ShelleyTransaction struct {
Inputs []ShelleyTransactionInput `cbor:"0,keyasint,omitempty"`
Outputs []ShelleyTransactionOutput `cbor:"1,keyasint,omitempty"`
Fee uint64 `cbor:"2,keyasint,omitempty"`
Ttl uint64 `cbor:"3,keyasint,omitempty"`
// TODO: figure out how to parse properly
Certificates []cbor.RawMessage `cbor:"4,keyasint,omitempty"`
// TODO: figure out how to parse this correctly
// We keep the raw CBOR because it can contain a map with []byte keys, which
// Go does not allow
Withdrawals cbor.RawMessage `cbor:"5,keyasint,omitempty"`
Update struct {
// Tells the CBOR decoder to convert to/from a struct and a CBOR array
_ struct{} `cbor:",toarray"`
// TODO: figure out how to parse properly
// We use RawMessage here because the content is arbitrary and can contain data that
// cannot easily be represented in Go (such as maps with bytestring keys)
ProtocolParamUpdates cbor.RawMessage
Epoch uint64
} `cbor:"6,keyasint,omitempty"`
MetadataHash Blake2b256 `cbor:"7,keyasint,omitempty"`
}

type ShelleyTransactionInput struct {
// Tells the CBOR decoder to convert to/from a struct and a CBOR array
_ struct{} `cbor:",toarray"`
Id Blake2b256
Index uint32
}

type ShelleyTransactionOutput struct {
// Tells the CBOR decoder to convert to/from a struct and a CBOR array
_ struct{} `cbor:",toarray"`
Address Blake2b256
Amount uint64
}

type ShelleyTransactionWitnessSet struct {
VkeyWitnesses []interface{} `cbor:"0,keyasint,omitempty"`
MultisigScripts []interface{} `cbor:"1,keyasint,omitempty"`
BootstrapWitnesses []interface{} `cbor:"2,keyasint,omitempty"`
}
Loading

0 comments on commit dc9cb0a

Please sign in to comment.