get serialization to work with sigs
This commit is contained in:
parent
a7b35770f0
commit
c1c77a72c8
|
@ -69,6 +69,7 @@ type txInToKey struct {
|
|||
|
||||
type TxInSerializer interface {
|
||||
TxInSerialize() []byte
|
||||
MixinLen() int
|
||||
}
|
||||
|
||||
type TxOut struct {
|
||||
|
@ -86,10 +87,7 @@ type TransactionPrefix struct {
|
|||
|
||||
type Transaction struct {
|
||||
TransactionPrefix
|
||||
signatures []Signature
|
||||
ringSignatures []RingSignature
|
||||
hash []byte
|
||||
blobSize uint32
|
||||
signatures [][]*Signature
|
||||
}
|
||||
|
||||
func (h *Hash) Serialize() (result []byte) {
|
||||
|
@ -151,6 +149,10 @@ func (t *txInGen) TxInSerialize() (result []byte) {
|
|||
return
|
||||
}
|
||||
|
||||
func (t *txInGen) MixinLen() int {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (t *txInToScript) TxInSerialize() (result []byte) {
|
||||
result = append([]byte{txInToScriptMarker}, t.prev...)
|
||||
result = append(result, Uint64ToBytes(t.prevOut)...)
|
||||
|
@ -158,6 +160,10 @@ func (t *txInToScript) TxInSerialize() (result []byte) {
|
|||
return
|
||||
}
|
||||
|
||||
func (t *txInToScript) MixinLen() int {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (t *txInToScriptHash) TxInSerialize() (result []byte) {
|
||||
result = append([]byte{txInToScriptHashMarker}, t.prev.Serialize()...)
|
||||
result = append(result, Uint64ToBytes(t.prevOut)...)
|
||||
|
@ -166,6 +172,10 @@ func (t *txInToScriptHash) TxInSerialize() (result []byte) {
|
|||
return
|
||||
}
|
||||
|
||||
func (t *txInToScriptHash) MixinLen() int {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (t *txInToKey) TxInSerialize() (result []byte) {
|
||||
result = append([]byte{txInToKeyMarker}, Uint64ToBytes(t.amount)...)
|
||||
result = append(result, Uint64ToBytes(uint64(len(t.keyOffsets)))...)
|
||||
|
@ -176,12 +186,16 @@ func (t *txInToKey) TxInSerialize() (result []byte) {
|
|||
return
|
||||
}
|
||||
|
||||
func (t *txInToKey) MixinLen() int {
|
||||
return len(t.keyOffsets)
|
||||
}
|
||||
|
||||
func (t *TxOut) Serialize() (result []byte) {
|
||||
result = append(Uint64ToBytes(t.amount), t.target.TargetSerialize()...)
|
||||
return
|
||||
}
|
||||
|
||||
func (t *TransactionPrefix) Serialize() (result []byte) {
|
||||
func (t *TransactionPrefix) SerializePrefix() (result []byte) {
|
||||
result = append(Uint64ToBytes(uint64(t.version)), Uint64ToBytes(t.unlockTime)...)
|
||||
result = append(result, Uint64ToBytes(uint64(len(t.vin)))...)
|
||||
for _, txIn := range t.vin {
|
||||
|
@ -196,6 +210,16 @@ func (t *TransactionPrefix) Serialize() (result []byte) {
|
|||
return
|
||||
}
|
||||
|
||||
func (t *Transaction) Serialize() (result []byte) {
|
||||
result = t.SerializePrefix()
|
||||
for i := 0; i < len(t.signatures); i++ {
|
||||
for j := 0; j < len(t.signatures[i]); j++ {
|
||||
result = append(result, t.signatures[i][j].Serialize()...)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func ParseTxInGen(buf *bytes.Buffer) (txIn *txInGen, err error) {
|
||||
t := new(txInGen)
|
||||
t.height, err = ReadVarInt(buf)
|
||||
|
@ -325,8 +349,42 @@ func ParseExtra(buf *bytes.Buffer) (extra []byte, err error) {
|
|||
return
|
||||
}
|
||||
|
||||
func ParseTransaction(buf *bytes.Buffer) (transaction *TransactionPrefix, err error) {
|
||||
t := new(TransactionPrefix)
|
||||
func ParseSignature(buf *bytes.Buffer) (signature *Signature, err error) {
|
||||
s := new(Signature)
|
||||
c := buf.Next(PubKeyLength)
|
||||
if len(c) != PubKeyLength {
|
||||
err = errors.New("Not enough bytes for signature c")
|
||||
return
|
||||
}
|
||||
copy(s.c[:], c)
|
||||
r := buf.Next(PubKeyLength)
|
||||
if len(r) != PubKeyLength {
|
||||
err = errors.New("Not enough bytes for signature r")
|
||||
return
|
||||
}
|
||||
copy(s.r[:], r)
|
||||
signature = s
|
||||
return
|
||||
}
|
||||
|
||||
func ParseSignatures(mixinLengths []int, buf *bytes.Buffer) (signatures [][]*Signature, err error) {
|
||||
// mixinLengths is the number of mixins at each input position
|
||||
sigs := make([][]*Signature, len(mixinLengths), len(mixinLengths))
|
||||
for i, nMixin := range mixinLengths {
|
||||
sigs[i] = make([]*Signature, nMixin, nMixin)
|
||||
for j := 0; j < nMixin; j++ {
|
||||
sigs[i][j], err = ParseSignature(buf)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
signatures = sigs
|
||||
return
|
||||
}
|
||||
|
||||
func ParseTransaction(buf *bytes.Buffer) (transaction *Transaction, err error) {
|
||||
t := new(Transaction)
|
||||
version, err := ReadVarInt(buf)
|
||||
if err != nil {
|
||||
return
|
||||
|
@ -340,12 +398,17 @@ func ParseTransaction(buf *bytes.Buffer) (transaction *TransactionPrefix, err er
|
|||
if err != nil {
|
||||
return
|
||||
}
|
||||
var mixinLengths []int
|
||||
t.vin = make([]TxInSerializer, int(numInputs), int(numInputs))
|
||||
for i := 0; i < int(numInputs); i++ {
|
||||
t.vin[i], err = ParseTxIn(buf)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
mixinLen := t.vin[i].MixinLen()
|
||||
if mixinLen > 0 {
|
||||
mixinLengths = append(mixinLengths, mixinLen)
|
||||
}
|
||||
}
|
||||
numOutputs, err := ReadVarInt(buf)
|
||||
if err != nil {
|
||||
|
@ -362,6 +425,14 @@ func ParseTransaction(buf *bytes.Buffer) (transaction *TransactionPrefix, err er
|
|||
if err != nil {
|
||||
return
|
||||
}
|
||||
t.signatures, err = ParseSignatures(mixinLengths, buf)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if buf.Len() != 0 {
|
||||
err = errors.New("Buffer has extra data")
|
||||
return
|
||||
}
|
||||
transaction = t
|
||||
return
|
||||
}
|
||||
|
|
|
@ -157,6 +157,7 @@ func TestTxInToKeyTransaction(t *testing.T) {
|
|||
outputSum uint64
|
||||
inputKeyImages []string
|
||||
outputs []string
|
||||
mixinLength int
|
||||
}{
|
||||
{
|
||||
name: "50 inputs from block 58272",
|
||||
|
@ -225,6 +226,7 @@ func TestTxInToKeyTransaction(t *testing.T) {
|
|||
"02bfae014409db5bbb21cfe04224b42a6476697df719ecc8b0d8ac65245c05482a",
|
||||
"022898f95d657d0fb76ebf551bea861d63657d71d53887df7f2aaa455c46488aaa",
|
||||
},
|
||||
mixinLength: 11,
|
||||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
|
@ -285,8 +287,20 @@ func TestTxInToKeyTransaction(t *testing.T) {
|
|||
t.Errorf("%s: output %d: want %x, got %x", test.name, i, wantOut, gotOut)
|
||||
}
|
||||
}
|
||||
wantLen = len(test.inputKeyImages)
|
||||
gotLen = len(transaction.signatures)
|
||||
if wantLen != gotLen {
|
||||
t.Errorf("%s: signature len: want %d, got %d", test.name, wantLen, gotLen)
|
||||
}
|
||||
for i, mixins := range transaction.signatures {
|
||||
wantLen = test.mixinLength
|
||||
gotLen = len(mixins)
|
||||
if wantLen != gotLen {
|
||||
t.Errorf("%s: mixin len for %d: want %d, got %d", test.name, i, wantLen, gotLen)
|
||||
}
|
||||
}
|
||||
gotSerialized := transaction.Serialize()
|
||||
wantSerialized := serializedTx[:len(gotSerialized)]
|
||||
wantSerialized := serializedTx
|
||||
if bytes.Compare(wantSerialized, gotSerialized) != 0 {
|
||||
t.Errorf("%s: serialized: want %x, got %x", test.name, wantSerialized, gotSerialized)
|
||||
}
|
||||
|
|
Reference in a new issue