Skip to content

Commit

Permalink
chore: add certified peer records to persisted peer store
Browse files Browse the repository at this point in the history
  • Loading branch information
vasco-santos committed Jun 29, 2020
1 parent 7f7611d commit 56e4dd9
Show file tree
Hide file tree
Showing 7 changed files with 299 additions and 118 deletions.
44 changes: 12 additions & 32 deletions src/identify/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,6 @@ class IdentifyService {
this._protocols = protocols

this.handleMessage = this.handleMessage.bind(this)

// TODO: this should be stored in the certified AddressBook in follow up PR
this._selfRecord = undefined
}

/**
Expand Down Expand Up @@ -204,19 +201,13 @@ class IdentifyService {
throw errCode(new Error(messages.ERR_INVALID_ENVELOPE), codes.ERR_INVALID_ENVELOPE)
}

// Decode peer record
let peerRecord
try {
peerRecord = await PeerRecord.createFromProtobuf(envelope.payload)
} catch (err) {
const consumed = this.peerStore.addressBook.consumePeerRecord(envelope)
if (!consumed) {
log('received invalid peer record, discard it')
throw errCode(new Error(messages.ERR_INVALID_PEER_RECORD), codes.ERR_INVALID_PEER_RECORD)
}

// TODO: Store as certified record

// Update peers data in PeerStore
this.peerStore.addressBook.set(id, peerRecord.multiaddrs.map((addr) => multiaddr(addr)))
// Update peer's protocols in PeerStore
this.peerStore.protoBook.set(id, protocols)

// TODO: Track our observed address so that we can score it
Expand Down Expand Up @@ -328,24 +319,12 @@ class IdentifyService {
throw errCode(new Error(messages.ERR_INVALID_ENVELOPE), codes.ERR_INVALID_ENVELOPE)
}

// Decode peer record
let peerRecord
try {
peerRecord = await PeerRecord.createFromProtobuf(envelope.payload)
} catch (err) {
const consumed = this.peerStore.addressBook.consumePeerRecord(envelope)
if (!consumed) {
log('received invalid peer record, discard it')
throw errCode(new Error(messages.ERR_INVALID_PEER_RECORD), codes.ERR_INVALID_PEER_RECORD)
}

// Update peers data in PeerStore
try {
// TODO: Store as certified record

this.peerStore.addressBook.set(id, peerRecord.multiaddrs.map((addr) => multiaddr(addr)))
} catch (err) {
return log.error('received invalid listen addrs', err)
}

// Update the protocols
this.peerStore.protoBook.set(id, message.protocols)
}
Expand All @@ -355,20 +334,21 @@ class IdentifyService {
* @return {Buffer}
*/
async _getSelfPeerRecord () {
// TODO: Verify if updated
if (this._selfRecord) {
return this._selfRecord
const selfSignedPeerRecord = this.peerStore.addressBook.getRawEnvelope(this.peerId)

// TODO: Verify if updated when we support dynamic addresses changes
if (selfSignedPeerRecord) {
return selfSignedPeerRecord
}

const peerRecord = new PeerRecord({
peerId: this.peerId,
multiaddrs: this._libp2p.multiaddrs
})
const envelope = await Envelope.seal(peerRecord, this.peerId)
this.peerStore.addressBook.consumePeerRecord(envelope)

this._selfRecord = envelope.marshal()

return this._selfRecord
return this.peerStore.addressBook.getRawEnvelope(this.peerId)
}
}

Expand Down
36 changes: 22 additions & 14 deletions src/peer-store/address-book.js
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,7 @@ class AddressBook extends Book {
const storedRecord = entry.record

// ensure seq is greater than, or equal to, the last received
if (storedRecord &&
storedRecord.seqNumber >= peerRecord.seqNumber) {
if (storedRecord && storedRecord.seqNumber >= peerRecord.seqNumber) {
return false
}

Expand All @@ -111,13 +110,8 @@ class AddressBook extends Book {

const addresses = this._toAddresses(peerRecord.multiaddrs, true)

// TODO: new record with different addresses from stored record
// - Remove the older ones?
// - Change to uncertified?

// TODO: events
// Should a multiaddr only modified to certified trigger an event?
// - Needed for persistent peer store
// Replace unsigned addresses by the new ones from the record
// TODO: Once we have ttls for the addresses, we should merge these in.
this._setData(peerId, {
addresses,
record: {
Expand All @@ -130,6 +124,21 @@ class AddressBook extends Book {
return true
}

/**
* Get a peer raw envelope.
* @param {PeerId} peerId
* @return {Buffer}
*/
getRawEnvelope (peerId) {
const entry = this.data.get(peerId.toB58String())

if (!entry || !entry.record || !entry.record.raw) {
return undefined
}

return entry.record.raw
}

/**
* Get an Envelope containing a PeerRecord for the given peer.
* @param {PeerId} peerId
Expand Down Expand Up @@ -170,7 +179,7 @@ class AddressBook extends Book {

// Already knows the peer
if (rec && rec.length === addresses.length) {
const intersection = rec.filter((mi) => addresses.some((newMi) => mi.multiaddr.equals(newMi.multiaddr)))
const intersection = rec.filter((addr) => addresses.some((newAddr) => addr.multiaddr.equals(newAddr.multiaddr)))

// Are new addresses equal to the old ones?
// If yes, no changes needed!
Expand Down Expand Up @@ -214,9 +223,9 @@ class AddressBook extends Book {
const rec = entry.addresses

// Add recorded uniquely to the new array (Union)
rec && rec.forEach((mi) => {
if (!addresses.find(r => r.multiaddr.equals(mi.multiaddr))) {
addresses.push(mi)
rec && rec.forEach((addr) => {
if (!addresses.find(r => r.multiaddr.equals(addr.multiaddr))) {
addresses.push(addr)
}
})

Expand Down Expand Up @@ -249,7 +258,6 @@ class AddressBook extends Book {
* @returns {Array<data>}
*/
get (peerId) {
// TODO: should we return Entry instead??
if (!PeerId.isPeerId(peerId)) {
throw errcode(new Error('peerId must be an instance of peer-id'), ERR_INVALID_PARAMETERS)
}
Expand Down
38 changes: 32 additions & 6 deletions src/peer-store/persistent/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -177,25 +177,47 @@ class PersistentPeerStore extends PeerStore {
const b32key = peerId.toString()
const key = new Key(`${NAMESPACE_ADDRESS}${b32key}`)

const addresses = this.addressBook.get(peerId)
const entry = this.addressBook.data.get(peerId.toB58String())

try {
// Deleted from the book
if (!addresses) {
if (!entry) {
batch.delete(key)
return
}

const encodedData = Addresses.encode({
addrs: addresses.map((address) => ({
addrs: entry.addresses.map((address) => ({
multiaddr: address.multiaddr.buffer
}))
})),
certified_record: entry.record ? {
seq: entry.record.seqNumber,
raw: entry.record.raw
} : undefined
})

batch.put(key, encodedData)
} catch (err) {
log.error(err)
}
// const addresses = this.addressBook.get(peerId)

// try {
// // Deleted from the book
// if (!addresses) {
// batch.delete(key)
// return
// }

// const encodedData = Addresses.encode({
// addrs: addresses.map((address) => ({
// multiaddr: address.multiaddr.buffer
// }))
// })

// batch.put(key, encodedData)
// } catch (err) {
// log.error(err)
// }
}

/**
Expand Down Expand Up @@ -299,7 +321,11 @@ class PersistentPeerStore extends PeerStore {
{
addresses: decoded.addrs.map((address) => ({
multiaddr: multiaddr(address.multiaddr)
}))
})),
record: decoded.certified_record ? {
raw: decoded.certified_record.raw,
seqNumber: decoded.certified_record.seq
} : undefined
},
{ emit: false })
break
Expand Down
5 changes: 3 additions & 2 deletions test/dialing/direct.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,7 @@ describe('Dialing (direct, WebSockets)', () => {
const connection = await libp2p.dial(remoteAddr)
expect(connection).to.exist()

sinon.spy(libp2p.peerStore.addressBook, 'set')
sinon.spy(libp2p.peerStore.addressBook, 'consumePeerRecord')
sinon.spy(libp2p.peerStore.protoBook, 'set')

// Wait for onConnection to be called
Expand All @@ -372,7 +372,8 @@ describe('Dialing (direct, WebSockets)', () => {
expect(libp2p.identifyService.identify.callCount).to.equal(1)
await libp2p.identifyService.identify.firstCall.returnValue

expect(libp2p.peerStore.addressBook.set.callCount).to.equal(1)
// Self + New peer
expect(libp2p.peerStore.addressBook.consumePeerRecord.callCount).to.equal(2)
expect(libp2p.peerStore.protoBook.set.callCount).to.equal(1)
})

Expand Down
Loading

0 comments on commit 56e4dd9

Please sign in to comment.