Skip to content

Commit

Permalink
added logic for send many tx
Browse files Browse the repository at this point in the history
  • Loading branch information
0xluk committed Apr 5, 2024
1 parent 8d0e2e3 commit 9f1f67e
Show file tree
Hide file tree
Showing 4 changed files with 154 additions and 2 deletions.
3 changes: 3 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,13 @@ require (
github.com/pkg/errors v0.9.1
github.com/qubic/cgo-schnorrq v1.0.0
github.com/silenceper/pool v1.0.0
github.com/stretchr/testify v1.2.2
)

require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/konsorten/go-windows-terminal-sequences v1.0.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/sirupsen/logrus v1.4.2 // indirect
golang.org/x/sys v0.3.0 // indirect
)
11 changes: 10 additions & 1 deletion qubic.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ package qubic
import (
"bytes"
"context"
"encoding/base64"
"encoding/binary"
"fmt"
"github.com/pkg/errors"
"github.com/qubic/go-node-connector/types"
"io"
Expand Down Expand Up @@ -212,6 +214,8 @@ func (qc *Client) sendRequest(ctx context.Context, requestType uint8, requestDat
return errors.Wrap(err, "serializing request")
}

fmt.Printf("req type: %d packet: %s", requestType, base64.StdEncoding.EncodeToString(packet))

err = qc.writePacketToConn(ctx, packet)
if err != nil {
return errors.Wrap(err, "sending packet to qubic conn")
Expand Down Expand Up @@ -313,7 +317,12 @@ func serializeRequest(ctx context.Context, requestType uint8, requestData interf
packetSize := uint32(packetHeaderSize + reqDataSize)

header.SetSize(packetSize)
header.RandomizeDejaVu()
if requestType == types.BroadcastTransaction {
header.ZeroDejaVu()
} else {
header.RandomizeDejaVu()
}

header.Type = requestType

serializedHeaderData, err := serializeBinary(header)
Expand Down
132 changes: 132 additions & 0 deletions types/transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,109 @@ import (
"io"
)

const SendManyMaxTransfers = 25
const QutilAddress = "EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVWRF"
const QutilSendManyInputType = 1
const QutilSendManyFee = 10
const QutilSendManyInputSize = 1000

type SendManyTransferPayload struct {
addresses [SendManyMaxTransfers][32]byte
amounts [SendManyMaxTransfers]int64
filledTransfers int8
totalAmount int64
}

type SendManyTransfer struct {
AddressID Identity
Amount int64
}

func (smp *SendManyTransferPayload) AddTransfer(transfer SendManyTransfer) error {
if smp.filledTransfers == SendManyMaxTransfers {
return errors.Errorf("max %d send many transfers allowed", SendManyMaxTransfers)
}

address, err := transfer.AddressID.ToPubKey(false)
if err != nil {
return errors.Wrap(err, "converting address id to byte form")
}

smp.addresses[smp.filledTransfers] = address
smp.amounts[smp.filledTransfers] = transfer.Amount
smp.filledTransfers += 1
smp.totalAmount += transfer.Amount

return nil
}

func (smp *SendManyTransferPayload) AddTransfers(transfers []SendManyTransfer) error {
if int(smp.filledTransfers)+len(transfers) > SendManyMaxTransfers {
return errors.Errorf("max %d send many transfers allowed", SendManyMaxTransfers)
}

for _, transfer := range transfers {
err := smp.AddTransfer(transfer)
if err != nil {
return errors.Wrapf(err, "adding transfer %+v", transfer)
}
}

return nil
}

func (smp *SendManyTransferPayload) GetTransfers() ([]SendManyTransfer, error) {
transfers := make([]SendManyTransfer, 0, SendManyMaxTransfers)
for index, address := range smp.addresses {
if address == [32]byte{} {
continue
}
var addrID Identity
addrID, err := addrID.FromPubKey(address, false)
if err != nil {
return nil, errors.Wrapf(err, "getting address identity from bytes %v", address)
}
transfers = append(transfers, SendManyTransfer{AddressID: addrID, Amount: smp.amounts[index]})
}

return transfers, nil
}

func (smp *SendManyTransferPayload) GetTotalAmount() int64 {
return smp.totalAmount
}

func (smp *SendManyTransferPayload) MarshallBinary() ([]byte, error) {
var buff bytes.Buffer
err := binary.Write(&buff, binary.LittleEndian, smp.addresses)
if err != nil {
return nil, errors.Wrap(err, "writing addresses to buf")
}

err = binary.Write(&buff, binary.LittleEndian, smp.amounts)
if err != nil {
return nil, errors.Wrap(err, "writing amounts to buf")
}

return buff.Bytes(), nil
}

func (smp *SendManyTransferPayload) UnmarshallBinary(b []byte) error {
reader := bytes.NewReader(b)

err := binary.Read(reader, binary.LittleEndian, &smp.addresses)
if err != nil {
return errors.Wrap(err, "reading addresses from reader")
}

err = binary.Read(reader, binary.LittleEndian, &smp.amounts)
if err != nil {
return errors.Wrap(err, "reading amounts from reader")
}

return nil
}

type Transaction struct {
SourcePublicKey [32]byte
DestinationPublicKey [32]byte
Expand Down Expand Up @@ -39,6 +142,35 @@ func NewSimpleTransferTransaction(sourceID, destinationID string, amount int64,
Tick: targetTick,
InputType: 0,
InputSize: 0,
Input: nil,
}, nil
}

func NewSendManyTransferTransaction(sourceID string, targetTick uint32, payload SendManyTransferPayload) (Transaction, error) {
srcID := Identity(sourceID)
destID := Identity(QutilAddress)
srcPubKey, err := srcID.ToPubKey(false)
if err != nil {
return Transaction{}, errors.Wrap(err, "converting src id string to pubkey")
}
destPubKey, err := destID.ToPubKey(false)
if err != nil {
return Transaction{}, errors.Wrap(err, "converting dest id string to pubkey")
}

input, err := payload.MarshallBinary()
if err != nil {
return Transaction{}, errors.Wrap(err, "binary marshalling payload")
}

return Transaction{
SourcePublicKey: srcPubKey,
DestinationPublicKey: destPubKey,
Amount: payload.GetTotalAmount(),
Tick: targetTick,
InputType: QutilSendManyInputType,
InputSize: QutilSendManyInputSize,
Input: input,
}, nil
}

Expand Down
10 changes: 9 additions & 1 deletion types/transaction_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@ package types
import (
"bytes"
"github.com/google/go-cmp/cmp"
"github.com/stretchr/testify/require"
"testing"
)

func TestTransaction_MarshallUnmarshall(t *testing.T) {
initialTx := Transaction{
SourcePublicKey: [32]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10},
SourcePublicKey: [32]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10},
DestinationPublicKey: [32]byte{11, 12, 13, 14, 15, 16, 17, 18, 19, 20},
Amount: 100,
Tick: 200,
Expand All @@ -33,3 +34,10 @@ func TestTransaction_MarshallUnmarshall(t *testing.T) {
t.Fatalf("Mismatched return value. Expected: %v, got: %v", initialTx, unmarshalledTx)
}
}

func TestSendManyTransferPayload_Size(t *testing.T) {
var payload SendManyTransferPayload
b, err := payload.MarshallBinary()
require.NoError(t, err, "binary marshalling payload")
require.True(t, len(b) == QutilSendManyInputSize)
}

0 comments on commit 9f1f67e

Please sign in to comment.