Completed pay/keysend test passing

This commit is contained in:
David Vennik
2023-01-14 16:05:17 +00:00
parent 59b1dd4bdd
commit 637e792fa6
14 changed files with 206 additions and 91 deletions

View File

@@ -88,8 +88,8 @@ func (cl *Client) RegisterConfirmation(hook confirm.Hook,
// FindCloaked searches the client identity key and the Sessions for a match. It // FindCloaked searches the client identity key and the Sessions for a match. It
// returns the session as well, though not all users of this function will need // returns the session as well, though not all users of this function will need
// this. // this.
func (cl *Client) FindCloaked(clk cloak.PubKey) (hdr *prv.Key, pld *prv.Key, func (cl *Client) FindCloaked(clk cloak.PubKey) (hdr *prv.Key,
sess *node.Session) { pld *prv.Key, sess *node.Session) {
var b cloak.Blinder var b cloak.Blinder
copy(b[:], clk[:cloak.BlindLen]) copy(b[:], clk[:cloak.BlindLen])
@@ -103,7 +103,7 @@ func (cl *Client) FindCloaked(clk cloak.PubKey) (hdr *prv.Key, pld *prv.Key,
for i := range cl.Sessions { for i := range cl.Sessions {
hash = cloak.Cloak(b, cl.Sessions[i].HeaderBytes) hash = cloak.Cloak(b, cl.Sessions[i].HeaderBytes)
if hash == clk { if hash == clk {
log.T.F("found in session %d", i) log.T.F("found cloaked key in session %d", i)
hdr = cl.Sessions[i].HeaderPrv hdr = cl.Sessions[i].HeaderPrv
pld = cl.Sessions[i].PayloadPrv pld = cl.Sessions[i].PayloadPrv
sess = cl.Sessions[i] sess = cl.Sessions[i]

View File

@@ -5,6 +5,7 @@ import (
"time" "time"
"github.com/cybriq/qu" "github.com/cybriq/qu"
"github.com/indra-labs/indra/pkg/key/prv"
"github.com/indra-labs/indra/pkg/node" "github.com/indra-labs/indra/pkg/node"
"github.com/indra-labs/indra/pkg/nonce" "github.com/indra-labs/indra/pkg/nonce"
"github.com/indra-labs/indra/pkg/sha256" "github.com/indra-labs/indra/pkg/sha256"
@@ -13,6 +14,7 @@ import (
"github.com/indra-labs/indra/pkg/transport" "github.com/indra-labs/indra/pkg/transport"
"github.com/indra-labs/indra/pkg/wire" "github.com/indra-labs/indra/pkg/wire"
"github.com/indra-labs/indra/pkg/wire/confirm" "github.com/indra-labs/indra/pkg/wire/confirm"
"github.com/indra-labs/indra/pkg/wire/session"
) )
func TestPing(t *testing.T) { func TestPing(t *testing.T) {
@@ -139,7 +141,47 @@ func TestSendKeys(t *testing.T) {
quit.Q() quit.Q()
// t.Error("SendKeys got stuck") // t.Error("SendKeys got stuck")
}() }()
// Create a new payment and drop on the payment channel.
sess := session.New()
pmt := sess.ToPayment(1000000)
clients[0].PaymentChan <- pmt
// Send the keys.
var circuit node.Circuit
for i := range circuit {
circuit[i] = clients[0].Sessions[i+1]
}
var hdr, pld [5]*prv.Key
hdr[0], pld[0] = sess.Header, sess.Payload
sk := wire.SendKeys(pmt.ID, hdr, pld, clients[0].Node,
circuit, clients[0].KeySet)
clients[0].RegisterConfirmation(func(cf nonce.ID) {
log.T.S("received payment confirmation ID", cf)
pp := clients[0].PendingPayments.Find(cf)
log.T.F("\nexpected %x\nreceived %x\nfrom\nhdr: %x\npld: %x",
sess.PreimageHash(),
pp.Preimage,
sess.Header.ToBytes(),
sess.Payload.ToBytes(),
)
if pp.Preimage != sess.PreimageHash() {
t.Errorf("did not find expected preimage: got"+
" %x expected %x",
pp.Preimage, sess.PreimageHash())
t.FailNow()
}
_ = pp
// if pp == nil {
// t.Errorf("did not find expected confirmation ID: got"+
// " %x expected %x", cf, pmt.ID)
// t.FailNow()
// }
log.T.F("SendKeys confirmed %x", cf)
time.Sleep(time.Second)
quit.Q()
}, pmt.ID)
o := sk.Assemble()
b := wire.EncodeOnion(o)
clients[0].Send(clients[0].Nodes[0].AddrPort, b)
<-quit.Wait() <-quit.Wait()
for _, v := range clients { for _, v := range clients {
v.Shutdown() v.Shutdown()

View File

@@ -11,7 +11,6 @@ import (
"github.com/indra-labs/indra/pkg/slice" "github.com/indra-labs/indra/pkg/slice"
"github.com/indra-labs/indra/pkg/types" "github.com/indra-labs/indra/pkg/types"
"github.com/indra-labs/indra/pkg/wire" "github.com/indra-labs/indra/pkg/wire"
"github.com/indra-labs/indra/pkg/wire/cipher"
"github.com/indra-labs/indra/pkg/wire/confirm" "github.com/indra-labs/indra/pkg/wire/confirm"
"github.com/indra-labs/indra/pkg/wire/delay" "github.com/indra-labs/indra/pkg/wire/delay"
"github.com/indra-labs/indra/pkg/wire/exit" "github.com/indra-labs/indra/pkg/wire/exit"
@@ -20,6 +19,7 @@ import (
"github.com/indra-labs/indra/pkg/wire/noop" "github.com/indra-labs/indra/pkg/wire/noop"
"github.com/indra-labs/indra/pkg/wire/response" "github.com/indra-labs/indra/pkg/wire/response"
"github.com/indra-labs/indra/pkg/wire/reverse" "github.com/indra-labs/indra/pkg/wire/reverse"
"github.com/indra-labs/indra/pkg/wire/session"
"github.com/indra-labs/indra/pkg/wire/token" "github.com/indra-labs/indra/pkg/wire/token"
) )
@@ -51,9 +51,9 @@ func (cl *Client) runner() (out bool) {
break break
} }
switch on := onion.(type) { switch on := onion.(type) {
case *cipher.OnionSkin: case *session.OnionSkin:
recLog(on, b, cl) recLog(on, b, cl)
cl.cipher(on, b, c) cl.session(on, b, c)
case *confirm.OnionSkin: case *confirm.OnionSkin:
recLog(on, b, cl) recLog(on, b, cl)
cl.confirm(on, b, c) cl.confirm(on, b, c)
@@ -84,11 +84,15 @@ func (cl *Client) runner() (out bool) {
default: default:
log.I.S("unrecognised packet", b) log.I.S("unrecognised packet", b)
} }
case p := <-cl.PaymentChan:
cl.PendingPayments = cl.PendingPayments.Add(p)
} }
return return
} }
func (cl *Client) cipher(on *cipher.OnionSkin, b slice.Bytes, c *slice.Cursor) { func (cl *Client) session(on *session.OnionSkin, b slice.Bytes,
c *slice.Cursor) {
// This either is in a forward only SendKeys message or we are the buyer // This either is in a forward only SendKeys message or we are the buyer
// and these are our session keys. // and these are our session keys.
// log.I.S(on) // log.I.S(on)
@@ -98,19 +102,25 @@ func (cl *Client) cipher(on *cipher.OnionSkin, b slice.Bytes, c *slice.Cursor) {
func (cl *Client) confirm(on *confirm.OnionSkin, b slice.Bytes, func (cl *Client) confirm(on *confirm.OnionSkin, b slice.Bytes,
c *slice.Cursor) { c *slice.Cursor) {
// When a confirm arrives check if it is registered for and run // When a confirm arrives check if it is registered for and run
// the hook that was registered with it. // the hook that was registered with it.
log.T.S(cl.Confirms)
cl.Confirms.Confirm(on.ID) cl.Confirms.Confirm(on.ID)
} }
func (cl *Client) delay(on *delay.OnionSkin, b slice.Bytes, cur *slice.Cursor) { func (cl *Client) delay(on *delay.OnionSkin, b slice.Bytes,
cur *slice.Cursor) {
// this is a message to hold the message in the buffer until a duration // this is a message to hold the message in the buffer until a duration
// elapses. The accounting for the remainder of the message adds a // elapses. The accounting for the remainder of the message adds a
// factor to the effective byte consumption in accordance with the time // factor to the effective byte consumption in accordance with the time
// to be stored. // to be stored.
} }
func (cl *Client) exit(on *exit.OnionSkin, b slice.Bytes, c *slice.Cursor) { func (cl *Client) exit(on *exit.OnionSkin, b slice.Bytes,
c *slice.Cursor) {
// payload is forwarded to a local port and the result is forwarded // payload is forwarded to a local port and the result is forwarded
// back with a reverse header. // back with a reverse header.
var e error var e error
@@ -156,7 +166,9 @@ func (cl *Client) forward(on *forward.OnionSkin, b slice.Bytes,
} }
} }
func (cl *Client) layer(on *layer.OnionSkin, b slice.Bytes, c *slice.Cursor) { func (cl *Client) layer(on *layer.OnionSkin, b slice.Bytes,
c *slice.Cursor) {
// this is probably an encrypted layer for us. // this is probably an encrypted layer for us.
hdr, _, _ := cl.FindCloaked(on.Cloak) hdr, _, _ := cl.FindCloaked(on.Cloak)
if hdr == nil { if hdr == nil {
@@ -168,7 +180,9 @@ func (cl *Client) layer(on *layer.OnionSkin, b slice.Bytes, c *slice.Cursor) {
cl.Node.Send(b) cl.Node.Send(b)
} }
func (cl *Client) noop(on *noop.OnionSkin, b slice.Bytes, c *slice.Cursor) { func (cl *Client) noop(on *noop.OnionSkin, b slice.Bytes,
c *slice.Cursor) {
// this won't happen normally // this won't happen normally
} }
@@ -214,6 +228,8 @@ func (cl *Client) reverse(on *reverse.OnionSkin, b slice.Bytes,
} }
cl.Node.Send(b[start:]) cl.Node.Send(b[start:])
default: default:
// If a reverse is not followed by an onion layer the
// message is incorrectly formed, just drop it.
return return
} }
} else { } else {
@@ -223,12 +239,16 @@ func (cl *Client) reverse(on *reverse.OnionSkin, b slice.Bytes,
} }
func (cl *Client) response(on *response.OnionSkin, b slice.Bytes, cur *slice.Cursor) { func (cl *Client) response(on *response.OnionSkin, b slice.Bytes,
cur *slice.Cursor) {
// Response is a payload from an exit message. // Response is a payload from an exit message.
cl.ExitHooks.Find(on.Hash, on.Bytes) cl.ExitHooks.Find(on.Hash, on.Bytes)
} }
func (cl *Client) token(t *token.OnionSkin, b slice.Bytes, cur *slice.Cursor) { func (cl *Client) token(t *token.OnionSkin, b slice.Bytes,
cur *slice.Cursor) {
// not really sure if we are using these. // not really sure if we are using these.
return return
} }

View File

@@ -38,8 +38,7 @@ func CreateMockCircuitClients() (clients []*Client, e error) {
clients[i].Node = nodes[i] clients[i].Node = nodes[i]
// create a session for all but the first // create a session for all but the first
if i > 0 { if i > 0 {
sessions[i-1] = node.NewSession(nonce.NewID(), sessions[i-1] = node.NewSession(nonce.NewID(), nodes[i], math.MaxUint64, nil, nil)
nodes[i], math.MaxUint64)
// Add session to node, so it will be able to relay if // Add session to node, so it will be able to relay if
// it gets a message with the key. // it gets a message with the key.
nodes[i].Sessions = append(nodes[i].Sessions, nodes[i].Sessions = append(nodes[i].Sessions,

View File

@@ -62,7 +62,7 @@ func New(addr *netip.AddrPort, idPub *pub.Key, idPrv *prv.Key,
IdentityPrv: idPrv, IdentityPrv: idPrv,
PaymentChan: make(PaymentChan), PaymentChan: make(PaymentChan),
} }
n.Sessions = append(n.Sessions, NewSession(id, n, 0)) n.Sessions = append(n.Sessions, NewSession(id, n, 0, nil, nil))
return return
} }

View File

@@ -2,10 +2,12 @@ package node
import ( import (
"github.com/indra-labs/indra/pkg/lnwire" "github.com/indra-labs/indra/pkg/lnwire"
"github.com/indra-labs/indra/pkg/nonce"
"github.com/indra-labs/indra/pkg/sha256" "github.com/indra-labs/indra/pkg/sha256"
) )
type Payment struct { type Payment struct {
nonce.ID
Preimage sha256.Hash Preimage sha256.Hash
Amount lnwire.MilliSatoshi Amount lnwire.MilliSatoshi
} }
@@ -32,9 +34,9 @@ func (p PendingPayments) Delete(preimage sha256.Hash) (pp PendingPayments) {
return return
} }
func (p PendingPayments) Find(preimage sha256.Hash) (pp *Payment) { func (p PendingPayments) Find(id nonce.ID) (pp *Payment) {
for i := range p { for i := range p {
if p[i].Preimage == preimage { if p[i].ID == id {
return p[i] return p[i]
} }
} }

View File

@@ -22,15 +22,17 @@ type Session struct {
// //
// Purchasing a session the seller returns a token, based on a requested data // Purchasing a session the seller returns a token, based on a requested data
// allocation. // allocation.
func NewSession(id nonce.ID, node *Node, rem uint64) (s *Session) { func NewSession(id nonce.ID, node *Node, rem uint64,
hdrPrv *prv.Key, pldPrv *prv.Key) (s *Session) {
var e error var e error
var hdrPrv, pldPrv *prv.Key if hdrPrv == nil || pldPrv == nil {
if hdrPrv, e = prv.GenerateKey(); check(e) { if hdrPrv, e = prv.GenerateKey(); check(e) {
}
if pldPrv, e = prv.GenerateKey(); check(e) {
}
} }
hdrPub := pub.Derive(hdrPrv) hdrPub := pub.Derive(hdrPrv)
if pldPrv, e = prv.GenerateKey(); check(e) {
}
pldPub := pub.Derive(pldPrv) pldPub := pub.Derive(pldPrv)
s = &Session{ s = &Session{
ID: id, ID: id,

View File

@@ -1,55 +0,0 @@
package cipher
import (
"github.com/indra-labs/indra"
"github.com/indra-labs/indra/pkg/key/prv"
"github.com/indra-labs/indra/pkg/key/pub"
log2 "github.com/indra-labs/indra/pkg/log"
"github.com/indra-labs/indra/pkg/slice"
"github.com/indra-labs/indra/pkg/types"
"github.com/indra-labs/indra/pkg/wire/magicbytes"
)
const (
MagicString = "cf"
Len = magicbytes.Len + pub.KeyLen*2
)
var (
log = log2.GetLogger(indra.PathBase)
check = log.E.Chk
Magic = slice.Bytes(MagicString)
_ types.Onion = &OnionSkin{}
)
// OnionSkin cipher delivers a pair of private keys to be used in association
// with a reply.Type specifically in the situation of a node bootstrapping
// sessions.
//
// After ~10 seconds these can be purged from the cache as they are otherwise a
// DoS vector buffer flooding.
type OnionSkin struct {
Header, Payload *prv.Key
types.Onion
}
func (x *OnionSkin) Inner() types.Onion { return x.Onion }
func (x *OnionSkin) Insert(o types.Onion) { x.Onion = o }
func (x *OnionSkin) Len() int { return Len + x.Onion.Len() }
func (x *OnionSkin) Encode(b slice.Bytes, c *slice.Cursor) {
copy(b[*c:c.Inc(magicbytes.Len)], Magic)
hdr := x.Header.ToBytes()
pld := x.Payload.ToBytes()
copy(b[*c:c.Inc(prv.KeyLen)], hdr[:])
copy(b[*c:c.Inc(prv.KeyLen)], pld[:])
x.Onion.Encode(b, c)
}
func (x *OnionSkin) Decode(b slice.Bytes, c *slice.Cursor) (e error) {
if len(b[*c:]) < Len-magicbytes.Len {
return magicbytes.TooShort(len(b[*c:]),
Len-magicbytes.Len, string(Magic))
}
x.Header = prv.PrivkeyFromBytes(b[*c:c.Inc(prv.KeyLen)])
x.Payload = prv.PrivkeyFromBytes(b[*c:c.Inc(prv.KeyLen)])
return
}

View File

@@ -8,7 +8,6 @@ import (
log2 "github.com/indra-labs/indra/pkg/log" log2 "github.com/indra-labs/indra/pkg/log"
"github.com/indra-labs/indra/pkg/slice" "github.com/indra-labs/indra/pkg/slice"
"github.com/indra-labs/indra/pkg/types" "github.com/indra-labs/indra/pkg/types"
"github.com/indra-labs/indra/pkg/wire/cipher"
"github.com/indra-labs/indra/pkg/wire/confirm" "github.com/indra-labs/indra/pkg/wire/confirm"
"github.com/indra-labs/indra/pkg/wire/delay" "github.com/indra-labs/indra/pkg/wire/delay"
"github.com/indra-labs/indra/pkg/wire/exit" "github.com/indra-labs/indra/pkg/wire/exit"
@@ -17,6 +16,7 @@ import (
"github.com/indra-labs/indra/pkg/wire/magicbytes" "github.com/indra-labs/indra/pkg/wire/magicbytes"
"github.com/indra-labs/indra/pkg/wire/response" "github.com/indra-labs/indra/pkg/wire/response"
"github.com/indra-labs/indra/pkg/wire/reverse" "github.com/indra-labs/indra/pkg/wire/reverse"
"github.com/indra-labs/indra/pkg/wire/session"
"github.com/indra-labs/indra/pkg/wire/token" "github.com/indra-labs/indra/pkg/wire/token"
) )
@@ -35,8 +35,8 @@ func EncodeOnion(on types.Onion) (b slice.Bytes) {
func PeelOnion(b slice.Bytes, c *slice.Cursor) (on types.Onion, e error) { func PeelOnion(b slice.Bytes, c *slice.Cursor) (on types.Onion, e error) {
switch b[*c:c.Inc(magicbytes.Len)].String() { switch b[*c:c.Inc(magicbytes.Len)].String() {
case cipher.MagicString: case session.MagicString:
o := &cipher.OnionSkin{} o := &session.OnionSkin{}
if e = o.Decode(b, c); check(e) { if e = o.Decode(b, c); check(e) {
return return
} }

View File

@@ -15,7 +15,6 @@ import (
"github.com/indra-labs/indra/pkg/slice" "github.com/indra-labs/indra/pkg/slice"
"github.com/indra-labs/indra/pkg/tests" "github.com/indra-labs/indra/pkg/tests"
"github.com/indra-labs/indra/pkg/types" "github.com/indra-labs/indra/pkg/types"
"github.com/indra-labs/indra/pkg/wire/cipher"
"github.com/indra-labs/indra/pkg/wire/confirm" "github.com/indra-labs/indra/pkg/wire/confirm"
"github.com/indra-labs/indra/pkg/wire/delay" "github.com/indra-labs/indra/pkg/wire/delay"
"github.com/indra-labs/indra/pkg/wire/exit" "github.com/indra-labs/indra/pkg/wire/exit"
@@ -23,6 +22,7 @@ import (
"github.com/indra-labs/indra/pkg/wire/layer" "github.com/indra-labs/indra/pkg/wire/layer"
"github.com/indra-labs/indra/pkg/wire/response" "github.com/indra-labs/indra/pkg/wire/response"
"github.com/indra-labs/indra/pkg/wire/reverse" "github.com/indra-labs/indra/pkg/wire/reverse"
"github.com/indra-labs/indra/pkg/wire/session"
"github.com/indra-labs/indra/pkg/wire/token" "github.com/indra-labs/indra/pkg/wire/token"
) )
@@ -40,9 +40,9 @@ func TestOnionSkins_Cipher(t *testing.T) {
if onc, e = PeelOnion(onb, c); check(e) { if onc, e = PeelOnion(onb, c); check(e) {
t.FailNow() t.FailNow()
} }
var ci *cipher.OnionSkin var ci *session.OnionSkin
var ok bool var ok bool
if ci, ok = onc.(*cipher.OnionSkin); !ok { if ci, ok = onc.(*session.OnionSkin); !ok {
t.Error("did not unwrap expected type") t.Error("did not unwrap expected type")
t.FailNow() t.FailNow()
} }

View File

@@ -10,7 +10,6 @@ import (
"github.com/indra-labs/indra/pkg/sha256" "github.com/indra-labs/indra/pkg/sha256"
"github.com/indra-labs/indra/pkg/slice" "github.com/indra-labs/indra/pkg/slice"
"github.com/indra-labs/indra/pkg/types" "github.com/indra-labs/indra/pkg/types"
"github.com/indra-labs/indra/pkg/wire/cipher"
"github.com/indra-labs/indra/pkg/wire/confirm" "github.com/indra-labs/indra/pkg/wire/confirm"
"github.com/indra-labs/indra/pkg/wire/delay" "github.com/indra-labs/indra/pkg/wire/delay"
"github.com/indra-labs/indra/pkg/wire/exit" "github.com/indra-labs/indra/pkg/wire/exit"
@@ -19,6 +18,7 @@ import (
"github.com/indra-labs/indra/pkg/wire/noop" "github.com/indra-labs/indra/pkg/wire/noop"
"github.com/indra-labs/indra/pkg/wire/response" "github.com/indra-labs/indra/pkg/wire/response"
"github.com/indra-labs/indra/pkg/wire/reverse" "github.com/indra-labs/indra/pkg/wire/reverse"
"github.com/indra-labs/indra/pkg/wire/session"
"github.com/indra-labs/indra/pkg/wire/token" "github.com/indra-labs/indra/pkg/wire/token"
) )
@@ -32,7 +32,7 @@ func (o OnionSkins) Cipher(hdr, pld *prv.Key) OnionSkins {
if hdr == nil || pld == nil { if hdr == nil || pld == nil {
return o return o
} }
return append(o, &cipher.OnionSkin{ return append(o, &session.OnionSkin{
Header: hdr, Header: hdr,
Payload: pld, Payload: pld,
Onion: &noop.OnionSkin{}, Onion: &noop.OnionSkin{},

View File

@@ -92,8 +92,8 @@ func SendExit(payload slice.Bytes, port uint16, client *node.Node,
// //
// This message's last layer is a Confirmation, which allows the client to know // This message's last layer is a Confirmation, which allows the client to know
// that the keys were successfully delivered. // that the keys were successfully delivered.
func SendKeys(id nonce.ID, hdr, pld []*prv.Key, func SendKeys(id nonce.ID, hdr, pld [5]*prv.Key,
client *node.Node, hop []*node.Node, set *signer.KeySet) OnionSkins { client *node.Node, hop node.Circuit, set *signer.KeySet) OnionSkins {
n := GenNonces(6) n := GenNonces(6)
return OnionSkins{}. return OnionSkins{}.

105
pkg/wire/session/session.go Normal file
View File

@@ -0,0 +1,105 @@
package session
import (
"github.com/indra-labs/indra"
"github.com/indra-labs/indra/pkg/key/prv"
"github.com/indra-labs/indra/pkg/lnwire"
log2 "github.com/indra-labs/indra/pkg/log"
"github.com/indra-labs/indra/pkg/node"
"github.com/indra-labs/indra/pkg/nonce"
"github.com/indra-labs/indra/pkg/sha256"
"github.com/indra-labs/indra/pkg/slice"
"github.com/indra-labs/indra/pkg/types"
"github.com/indra-labs/indra/pkg/wire/magicbytes"
"github.com/indra-labs/indra/pkg/wire/noop"
)
const (
MagicString = "ss"
Len = magicbytes.Len + prv.KeyLen*2
)
var (
log = log2.GetLogger(indra.PathBase)
check = log.E.Chk
Magic = slice.Bytes(MagicString)
_ types.Onion = &OnionSkin{}
)
// OnionSkin session delivers a pair of private keys to a relay that represent
// the preimage referred to in a Lightning payment for a session.
//
// The preimage is hashed by the buyer to use in the payment, and when the relay
// receives it, it can then hash the two private keys to match it with the
// payment preimage hash, which proves the buyer paid, and simultaneously
// provides the session keys that both forward and reverse messages will use,
// each in different ways.
//
// Exit nodes are provided the ciphers to encrypt for the three hops back to the
// client, but they do not have either public or private part of the Header or
// Payload keys of the return hops, which are used to conceal their respective
// message sections.
//
// Thus, they cannot decrypt the header, but they can encrypt the payload with
// the three layers of encryption that the reverse path hops have the private
// keys to decrypt. By this, the path in the header is concealed and the payload
// is concealed to the hops except for the encryption layer they decrypt using
// their Payload key, delivered in this message.
type OnionSkin struct {
Header, Payload *prv.Key
types.Onion
}
func New() (x *OnionSkin) {
var e error
var hdrPrv, pldPrv *prv.Key
if hdrPrv, e = prv.GenerateKey(); check(e) {
return
}
if pldPrv, e = prv.GenerateKey(); check(e) {
return
}
return &OnionSkin{
Header: hdrPrv,
Payload: pldPrv,
Onion: &noop.OnionSkin{},
}
}
func (x *OnionSkin) PreimageHash() sha256.Hash {
h, p := x.Header.ToBytes(), x.Payload.ToBytes()
return sha256.Single(append(h[:], p[:]...))
}
func (x *OnionSkin) ToPayment(amount lnwire.
MilliSatoshi) (p *node.Payment) {
p = &node.Payment{
ID: nonce.NewID(),
Preimage: x.PreimageHash(),
Amount: amount,
}
return
}
func (x *OnionSkin) Inner() types.Onion { return x.Onion }
func (x *OnionSkin) Insert(o types.Onion) { x.Onion = o }
func (x *OnionSkin) Len() int { return Len + x.Onion.Len() }
func (x *OnionSkin) Encode(b slice.Bytes, c *slice.Cursor) {
copy(b[*c:c.Inc(magicbytes.Len)], Magic)
hdr := x.Header.ToBytes()
pld := x.Payload.ToBytes()
copy(b[*c:c.Inc(prv.KeyLen)], hdr[:])
copy(b[*c:c.Inc(prv.KeyLen)], pld[:])
x.Onion.Encode(b, c)
}
func (x *OnionSkin) Decode(b slice.Bytes, c *slice.Cursor) (e error) {
if len(b[*c:]) < Len-magicbytes.Len {
return magicbytes.TooShort(len(b[*c:]),
Len-magicbytes.Len, string(Magic))
}
x.Header = prv.PrivkeyFromBytes(b[*c:c.Inc(prv.KeyLen)])
x.Payload = prv.PrivkeyFromBytes(b[*c:c.Inc(prv.KeyLen)])
return
}

View File

@@ -10,9 +10,9 @@ var (
// GitRef is the gitref, as in refs/heads/branchname. // GitRef is the gitref, as in refs/heads/branchname.
GitRef = "refs/heads/protocol" GitRef = "refs/heads/protocol"
// ParentGitCommit is the commit hash of the parent HEAD. // ParentGitCommit is the commit hash of the parent HEAD.
ParentGitCommit = "6f271556c60e5ff2a5915d48a1b4f9ed7559dff4" ParentGitCommit = "33257572125b76ba2bcad68dd54c92e2a4f44158"
// BuildTime stores the time when the current binary was built. // BuildTime stores the time when the current binary was built.
BuildTime = "2023-01-14T08:54:21Z" BuildTime = "2023-01-14T16:05:17Z"
// SemVer lists the (latest) git tag on the release. // SemVer lists the (latest) git tag on the release.
SemVer = "v0.1.7" SemVer = "v0.1.7"
// PathBase is the path base returned from runtime caller. // PathBase is the path base returned from runtime caller.