completed balance, confirmation, crypt, route
This commit is contained in:
@@ -22,24 +22,29 @@ var (
|
||||
)
|
||||
|
||||
const (
|
||||
BalanceMagic = "bala"
|
||||
BalanceLen = magic.Len + nonce.IDLen + slice.Uint64Len
|
||||
Magic = "bala"
|
||||
Len = magic.Len + nonce.IDLen + slice.Uint64Len
|
||||
)
|
||||
|
||||
// Balance is the balance with an ID the client has a pending balance update
|
||||
// waiting on.
|
||||
type Balance struct {
|
||||
ID nonce.ID
|
||||
lnwire.MilliSatoshi
|
||||
}
|
||||
|
||||
// Account simply records the message ID, which will be recognised in the pending
|
||||
// responses cache.
|
||||
func (x *Balance) Account(res *sess.Data, sm *sess.Manager,
|
||||
s *sessions.Data, last bool) (skip bool, sd *sessions.Data) {
|
||||
res.ID = x.ID
|
||||
return
|
||||
}
|
||||
|
||||
// Decode a splice.Splice's next bytes into a Balance.
|
||||
func (x *Balance) Decode(s *splice.Splice) (e error) {
|
||||
if e = magic.TooShort(s.Remaining(), BalanceLen-magic.Len,
|
||||
BalanceMagic); fails(e) {
|
||||
if e = magic.TooShort(s.Remaining(), Len-magic.Len,
|
||||
Magic); fails(e) {
|
||||
return
|
||||
}
|
||||
s.ReadID(&x.ID).
|
||||
@@ -47,20 +52,24 @@ func (x *Balance) Decode(s *splice.Splice) (e error) {
|
||||
return
|
||||
}
|
||||
|
||||
// Encode a Balance into a splice.Splice's next bytes.
|
||||
func (x *Balance) Encode(s *splice.Splice) (e error) {
|
||||
log.T.S("encoding", reflect.TypeOf(x),
|
||||
x.ID,
|
||||
x.MilliSatoshi,
|
||||
)
|
||||
s.
|
||||
Magic(BalanceMagic).
|
||||
Magic(Magic).
|
||||
ID(x.ID).
|
||||
Uint64(uint64(x.MilliSatoshi))
|
||||
return
|
||||
}
|
||||
|
||||
func (x *Balance) GetOnion() interface{} { return x }
|
||||
// GetOnion returns nothing because there isn't an onion inside a Balance.
|
||||
func (x *Balance) GetOnion() interface{} { return nil }
|
||||
|
||||
// Handle provides relay and accounting processing logic for receiving a Balance
|
||||
// message.
|
||||
func (x *Balance) Handle(s *splice.Splice, p ont.Onion, ng ont.Ngin) (e error) {
|
||||
log.D.Ln("handling balance", x.ID)
|
||||
log.D.S("pending", ng.Pending())
|
||||
@@ -71,13 +80,14 @@ func (x *Balance) Handle(s *splice.Splice, p ont.Onion, ng ont.Ngin) (e error) {
|
||||
out := int(session.Node.RelayRate) * s.Len()
|
||||
if session != nil {
|
||||
in := int(session.Node.RelayRate) * pending.SentSize
|
||||
shb := session.Header.Bytes
|
||||
switch {
|
||||
case i < 2:
|
||||
ng.Mgr().DecSession(session.Header.Bytes, in, true, "reverse")
|
||||
ng.Mgr().DecSession(shb, in, true, "reverse")
|
||||
case i == 2:
|
||||
ng.Mgr().DecSession(session.Header.Bytes, (in+out)/2, true, "getbalance")
|
||||
ng.Mgr().DecSession(shb, (in+out)/2, true, "getbalance")
|
||||
case i > 2:
|
||||
ng.Mgr().DecSession(session.Header.Bytes, out, true, "reverse")
|
||||
ng.Mgr().DecSession(shb, out, true, "reverse")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -100,13 +110,21 @@ func (x *Balance) Handle(s *splice.Splice, p ont.Onion, ng ont.Ngin) (e error) {
|
||||
return
|
||||
}
|
||||
|
||||
func (x *Balance) Len() int { return BalanceLen }
|
||||
func (x *Balance) Magic() string { return BalanceMagic }
|
||||
// Len returns the length of bytes required to encode the Balance.
|
||||
func (x *Balance) Len() int { return Len }
|
||||
|
||||
// Magic bytes that identify this message
|
||||
func (x *Balance) Magic() string { return Magic }
|
||||
|
||||
// Wrap is a no-op because a Balance is terminal.
|
||||
func (x *Balance) Wrap(inner ont.Onion) {}
|
||||
|
||||
func NewBalance(id nonce.ID, amt lnwire.MilliSatoshi) ont.Onion {
|
||||
// New creates a new Balance as an ont.Onion.
|
||||
func New(id nonce.ID, amt lnwire.MilliSatoshi) ont.Onion {
|
||||
return &Balance{ID: id, MilliSatoshi: amt}
|
||||
}
|
||||
|
||||
func balanceGen() codec.Codec { return &Balance{} }
|
||||
func init() { reg.Register(BalanceMagic, balanceGen) }
|
||||
// Gen is a factory function to generate an Ad.
|
||||
func Gen() codec.Codec { return &Balance{} }
|
||||
|
||||
func init() { reg.Register(Magic, Gen) }
|
||||
|
||||
@@ -19,7 +19,7 @@ func TestOnions_Balance(t *testing.T) {
|
||||
}
|
||||
id := nonce.NewID()
|
||||
sats := lnwire.MilliSatoshi(10000)
|
||||
on := ont.Assemble([]ont.Onion{NewBalance(id, sats)})
|
||||
on := ont.Assemble([]ont.Onion{New(id, sats)})
|
||||
s := ont.Encode(on)
|
||||
s.SetCursor(0)
|
||||
var onc codec.Codec
|
||||
|
||||
@@ -19,37 +19,47 @@ var (
|
||||
)
|
||||
|
||||
const (
|
||||
ConfirmationMagic = "conf"
|
||||
ConfirmationLen = magic.Len + nonce.IDLen + 1
|
||||
Magic = "conf"
|
||||
Len = magic.Len + nonce.IDLen
|
||||
)
|
||||
|
||||
// Confirmation is simply a nonce that associates with a pending circuit
|
||||
// transmission.
|
||||
//
|
||||
// If a reply is required there needs to be a RoutingHeader and cipher/nonce set.
|
||||
type Confirmation struct {
|
||||
ID nonce.ID
|
||||
Load byte
|
||||
ID nonce.ID
|
||||
}
|
||||
|
||||
// Account simply records the message ID, which will be recognised in the pending
|
||||
// responses cache.
|
||||
func (x *Confirmation) Account(res *sess.Data, sm *sess.Manager,
|
||||
s *sessions.Data, last bool) (skip bool, sd *sessions.Data) {
|
||||
res.ID = x.ID
|
||||
return
|
||||
}
|
||||
|
||||
// Decode a splice.Splice's next bytes into a Confirmation.
|
||||
func (x *Confirmation) Decode(s *splice.Splice) (e error) {
|
||||
if e = magic.TooShort(s.Remaining(), ConfirmationLen-magic.Len,
|
||||
ConfirmationMagic); fails(e) {
|
||||
if e = magic.TooShort(s.Remaining(), Len-magic.Len,
|
||||
Magic); fails(e) {
|
||||
return
|
||||
}
|
||||
s.ReadID(&x.ID).ReadByte(&x.Load)
|
||||
s.ReadID(&x.ID)
|
||||
return
|
||||
}
|
||||
|
||||
// Encode a Balance into a splice.Splice's next bytes.
|
||||
func (x *Confirmation) Encode(s *splice.Splice) (e error) {
|
||||
s.Magic(ConfirmationMagic).ID(x.ID).Byte(x.Load)
|
||||
s.Magic(Magic).ID(x.ID)
|
||||
return
|
||||
}
|
||||
|
||||
func (x *Confirmation) GetOnion() interface{} { return x }
|
||||
// GetOnion returns nothing because there isn't an onion inside a Confirmation.
|
||||
func (x *Confirmation) GetOnion() interface{} { return nil }
|
||||
|
||||
// Handle searches for a pending response and if it matches, runs the stored
|
||||
// callbacks attached to it.
|
||||
func (x *Confirmation) Handle(s *splice.Splice, p ont.Onion, ng ont.Ngin) (e error) {
|
||||
// When a confirmation arrives check if it is registered for and run the
|
||||
// hook that was registered with it.
|
||||
@@ -57,9 +67,19 @@ func (x *Confirmation) Handle(s *splice.Splice, p ont.Onion, ng ont.Ngin) (e err
|
||||
return
|
||||
}
|
||||
|
||||
func (x *Confirmation) Len() int { return ConfirmationLen }
|
||||
func (x *Confirmation) Magic() string { return ConfirmationMagic }
|
||||
func (x *Confirmation) Wrap(inner ont.Onion) {}
|
||||
func NewConfirmation(id nonce.ID, load byte) ont.Onion { return &Confirmation{ID: id, Load: load} }
|
||||
func confirmationGen() codec.Codec { return &Confirmation{} }
|
||||
func init() { reg.Register(ConfirmationMagic, confirmationGen) }
|
||||
// Len returns the length of bytes required to encode the Confirmation.
|
||||
func (x *Confirmation) Len() int { return Len }
|
||||
|
||||
// Magic bytes that identify this message
|
||||
func (x *Confirmation) Magic() string { return Magic }
|
||||
|
||||
// Wrap is a no-op because a Confirmation is terminal.
|
||||
func (x *Confirmation) Wrap(inner ont.Onion) {}
|
||||
|
||||
// New creates a new Confirmation.
|
||||
func New(id nonce.ID) ont.Onion { return &Confirmation{ID: id} }
|
||||
|
||||
// Gen is a factory function to generate an Ad.
|
||||
func Gen() codec.Codec { return &Confirmation{} }
|
||||
|
||||
func init() { reg.Register(Magic, Gen) }
|
||||
|
||||
@@ -17,7 +17,7 @@ func TestOnions_Confirmation(t *testing.T) {
|
||||
}
|
||||
id := nonce.NewID()
|
||||
var load byte = 128
|
||||
on := ont.Assemble([]ont.Onion{NewConfirmation(id, load)})
|
||||
on := ont.Assemble([]ont.Onion{New(id)})
|
||||
s := ont.Encode(on)
|
||||
s.SetCursor(0)
|
||||
var onc codec.Codec
|
||||
|
||||
@@ -33,18 +33,34 @@ const (
|
||||
CryptMagic = "cryp"
|
||||
)
|
||||
|
||||
// Crypt is an encrypted message, and forms the "skins" of the onions.
|
||||
type Crypt struct {
|
||||
Depth int
|
||||
|
||||
// Depth is used with RoutingHeaders to indicate which of the 3 layers in a
|
||||
// ReverseCrypt section.
|
||||
Depth int
|
||||
|
||||
// ToHeaderPub, ToPayloadPub are the public keys of the session.
|
||||
ToHeaderPub, ToPayloadPub *crypto.Pub
|
||||
From *crypto.Prv
|
||||
IV nonce.IV
|
||||
|
||||
// From is usually a one-time generated private key for which the public
|
||||
// counterpart combined with the recipient's private key generates the same
|
||||
// secret via ECDH.
|
||||
From *crypto.Prv
|
||||
|
||||
// IV is the Initialization Vector for the AES-CTR encryption used in a Crypt.
|
||||
IV nonce.IV
|
||||
|
||||
// The remainder here are for Decode.
|
||||
|
||||
// Cloak
|
||||
Cloak crypto.CloakedPubKey
|
||||
ToPriv *crypto.Prv
|
||||
FromPub *crypto.Pub
|
||||
ont.Onion
|
||||
}
|
||||
|
||||
// Account attaches the session, which is tied to the keys used in the crypt, to the pending result.
|
||||
func (x *Crypt) Account(res *sess.Data, sm *sess.Manager, s *sessions.Data,
|
||||
last bool) (skip bool, sd *sessions.Data) {
|
||||
|
||||
@@ -61,6 +77,7 @@ func (x *Crypt) Account(res *sess.Data, sm *sess.Manager, s *sessions.Data,
|
||||
return
|
||||
}
|
||||
|
||||
// Decode a splice.Splice's next bytes into a Crypt.
|
||||
func (x *Crypt) Decode(s *splice.Splice) (e error) {
|
||||
if e = magic.TooShort(s.Remaining(), consts.CryptLen-magic.Len,
|
||||
CryptMagic); fails(e) {
|
||||
@@ -78,6 +95,10 @@ func (x *Crypt) Decrypt(prk *crypto.Prv, s *splice.Splice) {
|
||||
x.IV, s.GetRest())
|
||||
}
|
||||
|
||||
// Encode a Crypt into a splice.Splice's next bytes.
|
||||
//
|
||||
// The crypt renders the inner contents first and once complete returns and
|
||||
// encrypts everything after the Crypt header.
|
||||
func (x *Crypt) Encode(s *splice.Splice) (e error) {
|
||||
log.T.F("encoding %s %s %x %x", reflect.TypeOf(x),
|
||||
x.ToHeaderPub, x.From.ToBytes(), x.IV,
|
||||
@@ -120,8 +141,11 @@ func (x *Crypt) Encode(s *splice.Splice) (e error) {
|
||||
return e
|
||||
}
|
||||
|
||||
// GetOnion returns the layers inside the crypt..
|
||||
func (x *Crypt) GetOnion() interface{} { return x }
|
||||
|
||||
// Handle provides relay and accounting processing logic for receiving a Crypt
|
||||
// message.
|
||||
func (x *Crypt) Handle(s *splice.Splice, p ont.Onion, ng ont.Ngin) (e error) {
|
||||
hdr, _, _, identity := ng.Mgr().FindCloaked(x.Cloak)
|
||||
if hdr == nil {
|
||||
@@ -143,11 +167,17 @@ func (x *Crypt) Handle(s *splice.Splice, p ont.Onion, ng ont.Ngin) (e error) {
|
||||
return e
|
||||
}
|
||||
|
||||
func (x *Crypt) Len() int { return consts.CryptLen + x.Onion.Len() }
|
||||
func (x *Crypt) Magic() string { return CryptMagic }
|
||||
// Len returns the length of bytes required to encode the Crypt.
|
||||
func (x *Crypt) Len() int { return consts.CryptLen + x.Onion.Len() }
|
||||
|
||||
// Magic bytes that identify this message
|
||||
func (x *Crypt) Magic() string { return CryptMagic }
|
||||
|
||||
// Wrap inserts an onion inside a Crypt.
|
||||
func (x *Crypt) Wrap(inner ont.Onion) { x.Onion = inner }
|
||||
|
||||
func NewCrypt(toHdr, toPld *crypto.Pub, from *crypto.Prv, iv nonce.IV,
|
||||
// New creates a new crypt message with an empty slot for more messages.
|
||||
func New(toHdr, toPld *crypto.Pub, from *crypto.Prv, iv nonce.IV,
|
||||
depth int) ont.Onion {
|
||||
return &Crypt{
|
||||
Depth: depth,
|
||||
@@ -159,5 +189,7 @@ func NewCrypt(toHdr, toPld *crypto.Pub, from *crypto.Prv, iv nonce.IV,
|
||||
}
|
||||
}
|
||||
|
||||
func cryptGen() codec.Codec { return &Crypt{} }
|
||||
func init() { reg.Register(CryptMagic, cryptGen) }
|
||||
// Gen is a factory function to generate an Crypt.
|
||||
func Gen() codec.Codec { return &Crypt{} }
|
||||
|
||||
func init() { reg.Register(CryptMagic, Gen) }
|
||||
|
||||
@@ -23,8 +23,8 @@ func TestOnions_SimpleCrypt(t *testing.T) {
|
||||
prv1, prv2 := crypto.GetTwoPrvKeys()
|
||||
pub1, pub2 := crypto.DerivePub(prv1), crypto.DerivePub(prv2)
|
||||
on := ont.Assemble([]ont.Onion{
|
||||
NewCrypt(pub1, pub2, prv2, n1, 0),
|
||||
confirmation.NewConfirmation(n, 0),
|
||||
New(pub1, pub2, prv2, n1, 0),
|
||||
confirmation.New(n),
|
||||
})
|
||||
s := ont.Encode(on)
|
||||
s.SetCursor(0)
|
||||
|
||||
@@ -166,11 +166,11 @@ func (x *Route) Handle(s *splice.Splice, p ont.Onion, ng ont.Ngin) (e error) {
|
||||
}
|
||||
rh := []ont.Onion{
|
||||
reverse.NewReverse(&addrs[0]),
|
||||
crypt.NewCrypt(rt.Sessions[0].Header.Pub, rt.Sessions[0].Payload.Pub, rt.Keys[0], rt.Nonces[0], 3),
|
||||
crypt.New(rt.Sessions[0].Header.Pub, rt.Sessions[0].Payload.Pub, rt.Keys[0], rt.Nonces[0], 3),
|
||||
reverse.NewReverse(&addrs[1]),
|
||||
crypt.NewCrypt(rt.Sessions[1].Header.Pub, rt.Sessions[1].Payload.Pub, rt.Keys[1], rt.Nonces[1], 2),
|
||||
crypt.New(rt.Sessions[1].Header.Pub, rt.Sessions[1].Payload.Pub, rt.Keys[1], rt.Nonces[1], 2),
|
||||
reverse.NewReverse(&addrs[2]),
|
||||
crypt.NewCrypt(rt.Sessions[2].Header.Pub, rt.Sessions[2].Payload.Pub, rt.Keys[2], rt.Nonces[2], 1),
|
||||
crypt.New(rt.Sessions[2].Header.Pub, rt.Sessions[2].Payload.Pub, rt.Keys[2], rt.Nonces[2], 1),
|
||||
}
|
||||
//.RoutingHeader(rt)
|
||||
rHdr := ont.Encode(ont.Assemble(rh))
|
||||
@@ -185,9 +185,9 @@ func (x *Route) Handle(s *splice.Splice, p ont.Onion, ng ont.Ngin) (e error) {
|
||||
}
|
||||
mr := []ont.Onion{
|
||||
forward.NewForward(&addrs[3]),
|
||||
crypt.NewCrypt(ss[3].Header.Pub, ss[3].Payload.Pub, ng.Keyset().Next(), n[3], 0),
|
||||
crypt.New(ss[3].Header.Pub, ss[3].Payload.Pub, ng.Keyset().Next(), n[3], 0),
|
||||
forward.NewForward(&addrs[4]),
|
||||
crypt.NewCrypt(ss[4].Header.Pub, ss[4].Payload.Pub, ng.Keyset().Next(), n[4], 0),
|
||||
crypt.New(ss[4].Header.Pub, ss[4].Payload.Pub, ng.Keyset().Next(), n[4], 0),
|
||||
ready.NewReady(x.ID, x.HiddenService,
|
||||
x.RoutingHeaderBytes,
|
||||
hidden.GetRoutingHeaderFromCursor(rHdr),
|
||||
|
||||
@@ -74,7 +74,7 @@ func TestDispatcher(t *testing.T) {
|
||||
var load1 byte = 128
|
||||
// var load2 byte = 32
|
||||
on1 := ont.Assemble(engine.Skins{
|
||||
confirmation.NewConfirmation(id1, load1)})
|
||||
confirmation.New(id1)})
|
||||
on2 := ont.Assemble(engine.Skins{
|
||||
response.NewResponse(id2, 0, msg1, 0)})
|
||||
s1 := ont.Encode(on1)
|
||||
|
||||
@@ -34,7 +34,7 @@ import (
|
||||
//}
|
||||
|
||||
func (o Skins) Confirmation(id nonce.ID, load byte) Skins {
|
||||
return append(o, confirmation.NewConfirmation(id, load))
|
||||
return append(o, confirmation.New(id))
|
||||
}
|
||||
|
||||
//func (o Skins) Delay(d time.Duration) Skins { return append(o, delay.NewDelay(d)) }
|
||||
@@ -143,7 +143,7 @@ func (o Skins) Reverse(ip *netip.AddrPort) Skins { return append(o, reverse.NewR
|
||||
func (o Skins) Crypt(toHdr, toPld *crypto.Pub, from *crypto.Prv, iv nonce.IV,
|
||||
depth int) Skins {
|
||||
|
||||
return append(o, crypt.NewCrypt(toHdr, toPld, from, iv, depth))
|
||||
return append(o, crypt.New(toHdr, toPld, from, iv, depth))
|
||||
}
|
||||
|
||||
// ReverseCrypt is a single layer of a RoutingHeader designating the session and relay for one of the hops in a Route.
|
||||
|
||||
Reference in New Issue
Block a user