Open richburdon opened 4 years ago
Short but important question about terms, does the "protocol" describe the fields which belong to the WNS record?
To use IPFS as the example, if I am registering an IPFS service record, and the type of the record is service
and the protocol is [ wrn://dxos/protocol/service/ipfs ]
what is the prospective content of wrn://dxos/protocol/service/ipfs ?
Is it:
A description of the fields which my IPFS service record in WNS should/must contain.
That, plus other things.
Not that at all.
@telackey No.
The schema for the Service record is fixed. It's defined by a protocol buffer message type that is part of the WNS code base. Similarly the schema of the Protocol record is fixed.
The CONTENTS of the Protocol record will be a set of protocol buffer type and service definitions. These text records will either be in a Protocol record field, or (more likely) linked via IPFS to a text document.
Service records may reference multiple Protocol records via the protocols
field.
NOTE: The reason record TYPES are fixed is that they have specific fixed semantics that the network uses to operate. Protocol definitions on the other hand have semantics that are interpreted by individual services, apps, or bots (e.g., Chess Protocol, File Store Protocol).
OK, I am missing a piece then. Don't we need some other thing which describes what fields an IPFS service record needs to have vs what fields a Signal service record needs to have?
For example, a Signal server, at a minimum, to support bootstrapping other signal nodes, must have a bootstrap field; and if it is accessible by endusers, it must have a WebSocket URL for clients to use. (You could have a record with one but not the other: a service just offering bootstrapping, or one just used for servicing clients.)
record:
type: 'service'
...
bootstrap: 'signal.example.com:4000'
url: 'wss://signal.example.com/dxos/signal'
An IPFS server on the other hand does not need any of these, but does need a field describing the IPFS protocol version being offered (not to be confused with our protocols) and an array of multiaddrs other IPFS servers can use to connect:
record:
type: 'service'
...
ipfs-protocol-version: 'ipfs/0.1.0',
addresses:
- '/ip4/208.69.42.151/tcp/29548/p2p/QmZrL5fSXKPM8UFCxKFdEBPdccziJgo7T4YeZLCPjzvUbq'
- '/ip6/FF:FF:FF:99/tcp/29548/p2p/QmZrL5fSXKPM8UFCxKFdEBPdccziJgo7T4YeZLCPjzvUbq'
OK good clear example.
So my feeling is there is a standard Record type for "service" records. What we might want is a payload field (not another record) that is typed by a protobuf schema. If we HAD to hack this today, we could do this by storing a JSON object in a key value field. I think this is close to what you want but: Rationale here is that this payload info is not queryable or separately addressable (which records are).
For clarity, my original proposal was something like this (the exact schema definition syntax is unimportant):
record:
type: type
name: ipfs
version: 1.0.0
schema:
ipfs-protocol-version: String!
addresses: [String!]!
wire wns set name wrn://dxos/type/service/ipfs <id>
record:
type: wrn://dxos/type/service/ipfs
...
ipfs-protocol-version: 'ipfs/0.1.0',
addresses:
- '/ip4/208.69.42.151/tcp/29548/p2p/QmZrL5fSXKPM8UFCxKFdEBPdccziJgo7T4YeZLCPjzvUbq'
- '/ip6/FF:FF:FF:99/tcp/29548/p2p/QmZrL5fSXKPM8UFCxKFdEBPdccziJgo7T4YeZLCPjzvUbq'
I can query for types across the system if I want, or define my own within my namespace if nothing available fits.
So then, in a few days when I realize I need a "Signal Service" or a "TURN Service" that has different fields and requirements than an "IPFS Service", I repeat the process of registering the name of the service type first, then registering my service.
If we wanted to combine this with the universal parent type "service", perhaps it would be something like this:
record:
type: service
service: wrn://dxos/service/ipfs
...
ipfs-protocol-version: 'ipfs/0.1.0',
addresses:
- '/ip4/208.69.42.151/tcp/29548/p2p/QmZrL5fSXKPM8UFCxKFdEBPdccziJgo7T4YeZLCPjzvUbq'
- '/ip6/FF:FF:FF:99/tcp/29548/p2p/QmZrL5fSXKPM8UFCxKFdEBPdccziJgo7T4YeZLCPjzvUbq'
Using the payload example, perhaps it would be something like this:
record:
type: service
service: wrn://dxos/service/ipfs
config: {
"ipfs-protocol-version": "ipfs/0.1.0",
"addresses" [ "....", "...." ]
}
A disadvantage I can see to the unqueryable payload scheme is that if it is 2021 and I am running an "ipfs/0.2.0" server, querying for WHERE service = 'wrn://dxos/service/ipfs' AND ipfs-protocol-version = 'ipfs/0.2.0'
is probably exactly what I want to do when choosing candidates for connection.
For reference it might also be worth noting what we have right now in the old WNS. There is mix of types, but most the service records look something like this (note that all existing types are prefixed with wrn:
):
record:
type: wrn:service
name: signal1.dxos.network
version: 1.0.0
description: signal1.dxos.network
service: ipfs
ipfs:
protocol: 'ipfs/0.1.0'
addresses:
- '/ip4/134.122.9.43/tcp/4001/p2p/QmUgmWfACwRafvAPTp2YBdNzezTDzZ1Tm7FF1PiEPxxHv8'
Type is always wrn:service
, and there is a service: <name>
attribute, so that one can query for type = 'wrn:service' AND service = 'ipfs'
. By convention, service
records have a map field named to match the value of the service field (eg, service: 'ipfs', ipfs: { ... }
or service: 'signal', signal: { ... }
.
The service: ipfs
record schema is sketched out here: https://github.com/wirelineio/wns/blob/master/x/nameservice/SCHEMA.md#wns
The major difference between what we have and what is proposed is that the value of type
(or perhaps service
) ought to be a WNS-registered name referring to a formal schema record, rather than an arbitrary name with schema described informally in markdown.
Following discussion with @dboreham
const services = [
// A
{
id: 'wrn://dxos.network/service/my-ipfs-service',
type: 'service',
api: [
{
id: 'wrn://dxos.network/protocol/imap/0.0.1', // => protobuf schema
muliAddr: ['192.168.1.100']
},
{
id: 'wrn://dxos.network/protocol/smpt/0.0.2',
muliAddr: ['192.168.1.100'],
encrypted: true
}
],
payments: [
{
id: 'wrn://dxos.network/payment/state-channel/0.0.1', // => protobuf schema
price: 'free'
}
],
meta: [
{
foo: 100
}
]
},
// B
{
id: 'wrn://dxos.network/service/my-ipfs-service',
type: 'service',
serviceType: 'wrn://dxos.network/protocol/ipfs/0.0.1', // => protobuf schema
price: 'free',
multiAddr: ['192.168.1.100'],
foo: 100
}
];
NOTE: The reason record TYPES are fixed is that they have specific fixed semantics that the network uses to operate. Protocol definitions on the other hand have semantics that are interpreted by individual services, apps, or bots (e.g., Chess Protocol, File Store Protocol).
@richburdon @ashwinphatak Which network is being discussed here? WNS does not need Protocol definitions to operate. I assume Ashwin has already defined whatever protobufs are required for WNS to operate.
Re: https://github.com/dxos/kube/issues/207