mirror of
https://github.com/yggdrasil-network/yggdrasil-go.git
synced 2026-05-24 23:06:29 +03:00
minor documentation updates, code comments, and a couple of bugfixes that I noticed when going through the code to comment it
This commit is contained in:
@@ -6,40 +6,52 @@ package yggdrasil
|
||||
import "sync"
|
||||
import "time"
|
||||
|
||||
// This keeps track of what signatures have already been checked.
|
||||
// It's used to skip expensive crypto operations, given that many signatures are likely to be the same for the average node's peers.
|
||||
type sigManager struct {
|
||||
mutex sync.RWMutex
|
||||
checked map[sigBytes]knownSig
|
||||
lastCleaned time.Time
|
||||
}
|
||||
|
||||
// Represents a known signature.
|
||||
// Includes the key, the signature bytes, the bytes that were signed, and the time it was last used.
|
||||
type knownSig struct {
|
||||
key sigPubKey
|
||||
sig sigBytes
|
||||
bs []byte
|
||||
time time.Time
|
||||
}
|
||||
|
||||
// Initializes the signature manager.
|
||||
func (m *sigManager) init() {
|
||||
m.checked = make(map[sigBytes]knownSig)
|
||||
}
|
||||
|
||||
// Checks if a key and signature match the supplied bytes.
|
||||
// If the same key/sig/bytes have been checked before, it returns true from the cached results.
|
||||
// If not, it checks the key, updates it in the cache if successful, and returns the checked results.
|
||||
func (m *sigManager) check(key *sigPubKey, sig *sigBytes, bs []byte) bool {
|
||||
if m.isChecked(sig, bs) {
|
||||
if m.isChecked(key, sig, bs) {
|
||||
return true
|
||||
}
|
||||
verified := verify(key, bs, sig)
|
||||
if verified {
|
||||
m.putChecked(sig, bs)
|
||||
m.putChecked(key, sig, bs)
|
||||
}
|
||||
return verified
|
||||
}
|
||||
|
||||
func (m *sigManager) isChecked(sig *sigBytes, bs []byte) bool {
|
||||
// Checks the cache to see if this key/sig/bytes combination has already been verified.
|
||||
// Returns true if it finds a match.
|
||||
func (m *sigManager) isChecked(key *sigPubKey, sig *sigBytes, bs []byte) bool {
|
||||
m.mutex.RLock()
|
||||
defer m.mutex.RUnlock()
|
||||
k, isIn := m.checked[*sig]
|
||||
if !isIn {
|
||||
return false
|
||||
}
|
||||
if len(bs) != len(k.bs) {
|
||||
if k.key != *key || k.sig != *sig || len(bs) != len(k.bs) {
|
||||
return false
|
||||
}
|
||||
for idx := 0; idx < len(bs); idx++ {
|
||||
@@ -51,7 +63,10 @@ func (m *sigManager) isChecked(sig *sigBytes, bs []byte) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (m *sigManager) putChecked(newsig *sigBytes, bs []byte) {
|
||||
// Puts a new result into the cache.
|
||||
// This result is then used by isChecked to skip the expensive crypto verification if it's needed again.
|
||||
// This is useful because, for nodes with multiple peers, there is often a lot of overlap between the signatures provided by each peer.
|
||||
func (m *sigManager) putChecked(key *sigPubKey, newsig *sigBytes, bs []byte) {
|
||||
m.mutex.Lock()
|
||||
defer m.mutex.Unlock()
|
||||
now := time.Now()
|
||||
@@ -64,6 +79,6 @@ func (m *sigManager) putChecked(newsig *sigBytes, bs []byte) {
|
||||
}
|
||||
m.lastCleaned = now
|
||||
}
|
||||
k := knownSig{bs: bs, time: now}
|
||||
k := knownSig{key: *key, sig: *newsig, bs: bs, time: now}
|
||||
m.checked[*newsig] = k
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user