Completed pay/keysend test passing
This commit is contained in:
@@ -88,8 +88,8 @@ func (cl *Client) RegisterConfirmation(hook confirm.Hook,
|
||||
// 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
|
||||
// this.
|
||||
func (cl *Client) FindCloaked(clk cloak.PubKey) (hdr *prv.Key, pld *prv.Key,
|
||||
sess *node.Session) {
|
||||
func (cl *Client) FindCloaked(clk cloak.PubKey) (hdr *prv.Key,
|
||||
pld *prv.Key, sess *node.Session) {
|
||||
|
||||
var b cloak.Blinder
|
||||
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 {
|
||||
hash = cloak.Cloak(b, cl.Sessions[i].HeaderBytes)
|
||||
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
|
||||
pld = cl.Sessions[i].PayloadPrv
|
||||
sess = cl.Sessions[i]
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"time"
|
||||
|
||||
"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/nonce"
|
||||
"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/wire"
|
||||
"github.com/indra-labs/indra/pkg/wire/confirm"
|
||||
"github.com/indra-labs/indra/pkg/wire/session"
|
||||
)
|
||||
|
||||
func TestPing(t *testing.T) {
|
||||
@@ -139,7 +141,47 @@ func TestSendKeys(t *testing.T) {
|
||||
quit.Q()
|
||||
// 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()
|
||||
for _, v := range clients {
|
||||
v.Shutdown()
|
||||
|
||||
@@ -11,7 +11,6 @@ import (
|
||||
"github.com/indra-labs/indra/pkg/slice"
|
||||
"github.com/indra-labs/indra/pkg/types"
|
||||
"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/delay"
|
||||
"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/response"
|
||||
"github.com/indra-labs/indra/pkg/wire/reverse"
|
||||
"github.com/indra-labs/indra/pkg/wire/session"
|
||||
"github.com/indra-labs/indra/pkg/wire/token"
|
||||
)
|
||||
|
||||
@@ -51,9 +51,9 @@ func (cl *Client) runner() (out bool) {
|
||||
break
|
||||
}
|
||||
switch on := onion.(type) {
|
||||
case *cipher.OnionSkin:
|
||||
case *session.OnionSkin:
|
||||
recLog(on, b, cl)
|
||||
cl.cipher(on, b, c)
|
||||
cl.session(on, b, c)
|
||||
case *confirm.OnionSkin:
|
||||
recLog(on, b, cl)
|
||||
cl.confirm(on, b, c)
|
||||
@@ -84,11 +84,15 @@ func (cl *Client) runner() (out bool) {
|
||||
default:
|
||||
log.I.S("unrecognised packet", b)
|
||||
}
|
||||
case p := <-cl.PaymentChan:
|
||||
cl.PendingPayments = cl.PendingPayments.Add(p)
|
||||
}
|
||||
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
|
||||
// and these are our session keys.
|
||||
// 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,
|
||||
c *slice.Cursor) {
|
||||
|
||||
// When a confirm arrives check if it is registered for and run
|
||||
// the hook that was registered with it.
|
||||
log.T.S(cl.Confirms)
|
||||
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
|
||||
// elapses. The accounting for the remainder of the message adds a
|
||||
// factor to the effective byte consumption in accordance with the time
|
||||
// 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
|
||||
// back with a reverse header.
|
||||
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.
|
||||
hdr, _, _ := cl.FindCloaked(on.Cloak)
|
||||
if hdr == nil {
|
||||
@@ -168,7 +180,9 @@ func (cl *Client) layer(on *layer.OnionSkin, b slice.Bytes, c *slice.Cursor) {
|
||||
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
|
||||
}
|
||||
|
||||
@@ -214,6 +228,8 @@ func (cl *Client) reverse(on *reverse.OnionSkin, b slice.Bytes,
|
||||
}
|
||||
cl.Node.Send(b[start:])
|
||||
default:
|
||||
// If a reverse is not followed by an onion layer the
|
||||
// message is incorrectly formed, just drop it.
|
||||
return
|
||||
}
|
||||
} 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.
|
||||
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.
|
||||
return
|
||||
}
|
||||
|
||||
@@ -38,8 +38,7 @@ func CreateMockCircuitClients() (clients []*Client, e error) {
|
||||
clients[i].Node = nodes[i]
|
||||
// create a session for all but the first
|
||||
if i > 0 {
|
||||
sessions[i-1] = node.NewSession(nonce.NewID(),
|
||||
nodes[i], math.MaxUint64)
|
||||
sessions[i-1] = node.NewSession(nonce.NewID(), nodes[i], math.MaxUint64, nil, nil)
|
||||
// Add session to node, so it will be able to relay if
|
||||
// it gets a message with the key.
|
||||
nodes[i].Sessions = append(nodes[i].Sessions,
|
||||
|
||||
@@ -62,7 +62,7 @@ func New(addr *netip.AddrPort, idPub *pub.Key, idPrv *prv.Key,
|
||||
IdentityPrv: idPrv,
|
||||
PaymentChan: make(PaymentChan),
|
||||
}
|
||||
n.Sessions = append(n.Sessions, NewSession(id, n, 0))
|
||||
n.Sessions = append(n.Sessions, NewSession(id, n, 0, nil, nil))
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -2,10 +2,12 @@ package node
|
||||
|
||||
import (
|
||||
"github.com/indra-labs/indra/pkg/lnwire"
|
||||
"github.com/indra-labs/indra/pkg/nonce"
|
||||
"github.com/indra-labs/indra/pkg/sha256"
|
||||
)
|
||||
|
||||
type Payment struct {
|
||||
nonce.ID
|
||||
Preimage sha256.Hash
|
||||
Amount lnwire.MilliSatoshi
|
||||
}
|
||||
@@ -32,9 +34,9 @@ func (p PendingPayments) Delete(preimage sha256.Hash) (pp PendingPayments) {
|
||||
return
|
||||
}
|
||||
|
||||
func (p PendingPayments) Find(preimage sha256.Hash) (pp *Payment) {
|
||||
func (p PendingPayments) Find(id nonce.ID) (pp *Payment) {
|
||||
for i := range p {
|
||||
if p[i].Preimage == preimage {
|
||||
if p[i].ID == id {
|
||||
return p[i]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,15 +22,17 @@ type Session struct {
|
||||
//
|
||||
// Purchasing a session the seller returns a token, based on a requested data
|
||||
// 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 hdrPrv, pldPrv *prv.Key
|
||||
if hdrPrv, e = prv.GenerateKey(); check(e) {
|
||||
if hdrPrv == nil || pldPrv == nil {
|
||||
if hdrPrv, e = prv.GenerateKey(); check(e) {
|
||||
}
|
||||
if pldPrv, e = prv.GenerateKey(); check(e) {
|
||||
}
|
||||
}
|
||||
hdrPub := pub.Derive(hdrPrv)
|
||||
if pldPrv, e = prv.GenerateKey(); check(e) {
|
||||
}
|
||||
pldPub := pub.Derive(pldPrv)
|
||||
s = &Session{
|
||||
ID: id,
|
||||
|
||||
@@ -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
|
||||
}
|
||||
@@ -8,7 +8,6 @@ import (
|
||||
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/cipher"
|
||||
"github.com/indra-labs/indra/pkg/wire/confirm"
|
||||
"github.com/indra-labs/indra/pkg/wire/delay"
|
||||
"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/response"
|
||||
"github.com/indra-labs/indra/pkg/wire/reverse"
|
||||
"github.com/indra-labs/indra/pkg/wire/session"
|
||||
"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) {
|
||||
switch b[*c:c.Inc(magicbytes.Len)].String() {
|
||||
case cipher.MagicString:
|
||||
o := &cipher.OnionSkin{}
|
||||
case session.MagicString:
|
||||
o := &session.OnionSkin{}
|
||||
if e = o.Decode(b, c); check(e) {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -15,7 +15,6 @@ import (
|
||||
"github.com/indra-labs/indra/pkg/slice"
|
||||
"github.com/indra-labs/indra/pkg/tests"
|
||||
"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/delay"
|
||||
"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/response"
|
||||
"github.com/indra-labs/indra/pkg/wire/reverse"
|
||||
"github.com/indra-labs/indra/pkg/wire/session"
|
||||
"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) {
|
||||
t.FailNow()
|
||||
}
|
||||
var ci *cipher.OnionSkin
|
||||
var ci *session.OnionSkin
|
||||
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.FailNow()
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@ import (
|
||||
"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/cipher"
|
||||
"github.com/indra-labs/indra/pkg/wire/confirm"
|
||||
"github.com/indra-labs/indra/pkg/wire/delay"
|
||||
"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/response"
|
||||
"github.com/indra-labs/indra/pkg/wire/reverse"
|
||||
"github.com/indra-labs/indra/pkg/wire/session"
|
||||
"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 {
|
||||
return o
|
||||
}
|
||||
return append(o, &cipher.OnionSkin{
|
||||
return append(o, &session.OnionSkin{
|
||||
Header: hdr,
|
||||
Payload: pld,
|
||||
Onion: &noop.OnionSkin{},
|
||||
|
||||
@@ -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
|
||||
// that the keys were successfully delivered.
|
||||
func SendKeys(id nonce.ID, hdr, pld []*prv.Key,
|
||||
client *node.Node, hop []*node.Node, set *signer.KeySet) OnionSkins {
|
||||
func SendKeys(id nonce.ID, hdr, pld [5]*prv.Key,
|
||||
client *node.Node, hop node.Circuit, set *signer.KeySet) OnionSkins {
|
||||
|
||||
n := GenNonces(6)
|
||||
return OnionSkins{}.
|
||||
|
||||
105
pkg/wire/session/session.go
Normal file
105
pkg/wire/session/session.go
Normal 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
|
||||
}
|
||||
@@ -10,9 +10,9 @@ var (
|
||||
// GitRef is the gitref, as in refs/heads/branchname.
|
||||
GitRef = "refs/heads/protocol"
|
||||
// ParentGitCommit is the commit hash of the parent HEAD.
|
||||
ParentGitCommit = "6f271556c60e5ff2a5915d48a1b4f9ed7559dff4"
|
||||
ParentGitCommit = "33257572125b76ba2bcad68dd54c92e2a4f44158"
|
||||
// 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 = "v0.1.7"
|
||||
// PathBase is the path base returned from runtime caller.
|
||||
|
||||
Reference in New Issue
Block a user