feat: Waku v2 bridge

Issue #12610
This commit is contained in:
Michal Iskierko
2023-11-12 13:29:38 +01:00
parent 56e7bd01ca
commit 6d31343205
6716 changed files with 1982502 additions and 5891 deletions

27
vendor/github.com/anacrolix/dht/v2/bep44/error.go generated vendored Normal file
View File

@@ -0,0 +1,27 @@
package bep44
import "github.com/anacrolix/dht/v2/krpc"
var (
ErrValueFieldTooBig = krpc.Error{
Code: krpc.ErrorCodeMessageValueFieldTooBig,
Msg: "message (v field) too big",
}
ErrInvalidSignature = krpc.Error{
Code: krpc.ErrorCodeInvalidSignature,
Msg: "invalid signature",
}
ErrSaltFieldTooBig = krpc.Error{
Code: krpc.ErrorCodeSaltFieldTooBig,
Msg: "salt (salt field) too big",
}
ErrCasHashMismatched = krpc.Error{
Code: krpc.ErrorCodeCasHashMismatched,
Msg: "the CAS hash mismatched, re-read value and try again",
}
ErrSequenceNumberLessThanCurrent = krpc.Error{
Code: krpc.ErrorCodeSequenceNumberLessThanCurrent,
Msg: "sequence number less than current",
}
)

177
vendor/github.com/anacrolix/dht/v2/bep44/item.go generated vendored Normal file
View File

@@ -0,0 +1,177 @@
package bep44
import (
"bytes"
"crypto/ed25519"
"crypto/sha1"
"fmt"
"time"
"github.com/anacrolix/torrent/bencode"
)
var Empty32ByteArray [32]byte
type Item struct {
// time when this object was added to storage
created time.Time
// Value to be stored
V interface{}
// 32 byte ed25519 public key
K [32]byte
Salt []byte
Sig [64]byte
Cas int64
Seq int64
}
func (i *Item) ToPut() Put {
p := Put{
V: i.V,
Salt: i.Salt,
Sig: i.Sig,
Cas: i.Cas,
Seq: i.Seq,
}
if i.K != Empty32ByteArray {
p.K = &i.K
}
return p
}
// NewItem creates a new arbitrary DHT element. The distinction between storing mutable
// and immutable items is the inclusion of a public key, a sequence number, signature
// and an optional salt.
//
// cas parameter is short for compare and swap, it has similar semantics as CAS CPU
// instructions. It is used to avoid race conditions when multiple nodes are writing
// to the same slot in the DHT. It is optional. If present it specifies the sequence
// number of the data blob being overwritten by the put.
//
// salt parameter is used to make possible several targets using the same private key.
//
// The optional seq field specifies that an item's value should only be sent if its
// sequence number is greater than the given value.
func NewItem(value interface{}, salt []byte, seq, cas int64, k ed25519.PrivateKey) (*Item, error) {
v, err := bencode.Marshal(value)
if err != nil {
return nil, err
}
var kk [32]byte
var sig [64]byte
if k != nil {
pk := []byte(k.Public().(ed25519.PublicKey))
copy(kk[:], pk)
copy(sig[:], Sign(k, salt, seq, v))
}
return &Item{
V: value,
Salt: salt,
Cas: cas,
Seq: seq,
K: kk,
Sig: sig,
}, nil
}
func (i *Item) Target() Target {
if i.IsMutable() {
return sha1.Sum(append(i.K[:], i.Salt...))
}
return sha1.Sum(bencode.MustMarshal(i.V))
}
func (i *Item) Modify(value interface{}, k ed25519.PrivateKey) bool {
if !i.IsMutable() {
return false
}
v, err := bencode.Marshal(value)
if err != nil {
return false
}
i.V = value
i.Seq++
var sig [64]byte
copy(sig[:], Sign(k, i.Salt, i.Seq, v))
i.Sig = sig
return true
}
func (s *Item) IsMutable() bool {
return s.K != Empty32ByteArray
}
func bufferToSign(salt, bv []byte, seq int64) []byte {
var bts []byte
if len(salt) != 0 {
bts = append(bts, []byte("4:salt")...)
x := bencode.MustMarshal(salt)
bts = append(bts, x...)
}
bts = append(bts, []byte(fmt.Sprintf("3:seqi%de1:v", seq))...)
bts = append(bts, bv...)
return bts
}
func Check(i *Item) error {
bv, err := bencode.Marshal(i.V)
if err != nil {
return err
}
if len(bv) > 1000 {
return ErrValueFieldTooBig
}
if !i.IsMutable() {
return nil
}
if len(i.Salt) > 64 {
return ErrSaltFieldTooBig
}
if !Verify(i.K[:], i.Salt, i.Seq, bv, i.Sig[:]) {
return ErrInvalidSignature
}
return nil
}
func CheckIncoming(stored, incoming *Item) error {
// If the sequence number is equal, and the value is also the same,
// the node SHOULD reset its timeout counter.
if stored.Seq == incoming.Seq {
if bytes.Equal(
bencode.MustMarshal(stored.V),
bencode.MustMarshal(incoming.V),
) {
return nil
}
}
if stored.Seq >= incoming.Seq {
return ErrSequenceNumberLessThanCurrent
}
// Cas should be ignored if not present
if stored.Cas == 0 {
return nil
}
if stored.Cas != incoming.Cas {
return ErrCasHashMismatched
}
return nil
}

13
vendor/github.com/anacrolix/dht/v2/bep44/key.go generated vendored Normal file
View File

@@ -0,0 +1,13 @@
package bep44
import (
"crypto/ed25519"
)
func Sign(k ed25519.PrivateKey, salt []byte, seq int64, bv []byte) []byte {
return ed25519.Sign(k, bufferToSign(salt, bv, seq))
}
func Verify(k ed25519.PublicKey, salt []byte, seq int64, bv []byte, sig []byte) bool {
return ed25519.Verify(k, bufferToSign(salt, bv, seq), sig)
}

49
vendor/github.com/anacrolix/dht/v2/bep44/memory.go generated vendored Normal file
View File

@@ -0,0 +1,49 @@
package bep44
import (
"sync"
)
var _ Store = &Memory{}
type Memory struct {
// protects m
mu sync.RWMutex
m map[Target]*Item
}
func NewMemory() *Memory {
return &Memory{
m: make(map[Target]*Item),
}
}
func (m *Memory) Put(i *Item) error {
m.mu.Lock()
defer m.mu.Unlock()
m.m[i.Target()] = i
return nil
}
func (m *Memory) Get(t Target) (*Item, error) {
m.mu.Lock()
defer m.mu.Unlock()
i, ok := m.m[t]
if !ok {
return nil, ErrItemNotFound
}
return i, nil
}
func (m *Memory) Del(t Target) error {
m.mu.Lock()
defer m.mu.Unlock()
delete(m.m, t)
return nil
}

47
vendor/github.com/anacrolix/dht/v2/bep44/put.go generated vendored Normal file
View File

@@ -0,0 +1,47 @@
package bep44
import (
"crypto/ed25519"
"crypto/sha1"
"github.com/anacrolix/torrent/bencode"
)
type Put struct {
V interface{}
K *[32]byte
Salt []byte
Sig [64]byte
Cas int64
Seq int64
}
func (p *Put) ToItem() *Item {
i := &Item{
V: p.V,
Salt: p.Salt,
Sig: p.Sig,
Cas: p.Cas,
Seq: p.Seq,
}
if p.K != nil {
i.K = *p.K
}
return i
}
func (p *Put) Sign(k ed25519.PrivateKey) {
copy(p.Sig[:], Sign(k, p.Salt, p.Seq, bencode.MustMarshal(p.V)))
}
func (i *Put) Target() Target {
if i.IsMutable() {
return MakeMutableTarget(*i.K, i.Salt)
} else {
return sha1.Sum(bencode.MustMarshal(i.V))
}
}
func (s *Put) IsMutable() bool {
return s.K != nil
}

65
vendor/github.com/anacrolix/dht/v2/bep44/store.go generated vendored Normal file
View File

@@ -0,0 +1,65 @@
package bep44
import (
"errors"
"time"
)
var ErrItemNotFound = errors.New("item not found")
type Store interface {
Put(*Item) error
Get(Target) (*Item, error)
Del(Target) error
}
// Wrapper is in charge of validate all new items and
// decide when to store, or ignore them depending of the BEP 44 definition.
// It is also in charge of removing expired items.
type Wrapper struct {
s Store
exp time.Duration
}
func NewWrapper(s Store, exp time.Duration) *Wrapper {
return &Wrapper{s: s, exp: exp}
}
func (w *Wrapper) Put(i *Item) error {
if err := Check(i); err != nil {
return err
}
is, err := w.s.Get(i.Target())
if errors.Is(err, ErrItemNotFound) {
i.created = time.Now().Local()
return w.s.Put(i)
}
if err != nil {
return err
}
if err := CheckIncoming(is, i); err != nil {
return err
}
i.created = time.Now().Local()
return w.s.Put(i)
}
func (w *Wrapper) Get(t Target) (*Item, error) {
i, err := w.s.Get(t)
if err != nil {
return nil, err
}
if i.created.Add(w.exp).After(time.Now().Local()) {
return i, nil
}
if err := w.s.Del(t); err != nil {
return nil, err
}
return nil, ErrItemNotFound
}

11
vendor/github.com/anacrolix/dht/v2/bep44/target.go generated vendored Normal file
View File

@@ -0,0 +1,11 @@
package bep44
import (
"crypto/sha1"
)
type Target = [sha1.Size]byte
func MakeMutableTarget(pubKey [32]byte, salt []byte) Target {
return sha1.Sum(append(pubKey[:], salt...))
}