Skip to content

Commit

Permalink
refactor: SpendTx struct deserialization
Browse files Browse the repository at this point in the history
  • Loading branch information
randomshinichi committed Aug 13, 2019
1 parent a19900f commit b5c3812
Show file tree
Hide file tree
Showing 2 changed files with 120 additions and 0 deletions.
52 changes: 52 additions & 0 deletions aeternity/transactions.go
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,20 @@ type SpendTx struct {
Nonce uint64
}

// Equal compares the receiver to another struct of the same type. This is
// needed because several types in Golang are difficult to compare, especially
// using reflect.DeepEqual.
func (tx *SpendTx) Equal(other *SpendTx) (equal bool) {
equal = (tx.SenderID == other.SenderID &&
tx.RecipientID == other.RecipientID &&
tx.Amount.Cmp(&other.Amount) == 0 &&
tx.Fee.Cmp(&other.Fee) == 0 &&
bytes.Equal(tx.Payload, other.Payload) &&
tx.TTL == other.TTL &&
tx.Nonce == other.Nonce)
return
}

// EncodeRLP implements rlp.Encoder
func (tx *SpendTx) EncodeRLP(w io.Writer) (err error) {
// build id for the sender
Expand Down Expand Up @@ -259,6 +273,44 @@ func (tx *SpendTx) EncodeRLP(w io.Writer) (err error) {
return nil
}

type spendtx struct {
ObjectTagSpendTransaction uint
RlpMessageVersion uint
SenderID []uint8
ReceiverID []uint8
Amount big.Int
Fee big.Int
TTL uint64
Nonce uint64
Payload []byte
}

func (tx *SpendTx) DecodeRLP(s *rlp.Stream) (err error) {
stx := &spendtx{}
blob, err := s.Raw()
err = rlp.DecodeBytes(blob, stx)
if err != nil {
return err
}

_, sID, err := readIDTag(stx.SenderID)
if err != nil {
return err
}
_, rID, err := readIDTag(stx.ReceiverID)
if err != nil {
return err
}
tx.SenderID = sID
tx.RecipientID = rID
tx.Amount = stx.Amount
tx.Fee = stx.Fee
tx.TTL = stx.TTL
tx.Nonce = stx.Nonce
tx.Payload = stx.Payload
return
}

// JSON representation of a Tx is useful for querying the node's debug endpoint
func (tx *SpendTx) JSON() (string, error) {
baseEncodedPayload := Encode(PrefixByteArray, tx.Payload)
Expand Down
68 changes: 68 additions & 0 deletions aeternity/transactions_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"testing"

"github.com/aeternity/aepp-sdk-go/utils"
rlp "github.com/randomshinichi/rlpae"
)

func getRLPSerialized(tx1 string, tx2 string) ([]interface{}, []interface{}) {
Expand Down Expand Up @@ -76,6 +77,8 @@ func TestSpendTx_EncodeRLP(t *testing.T) {
txJSON, err := tx.JSON()
fmt.Println(txJSON)

fmt.Println(rlp.EncodeToBytes(&tx))

gotTx, err := SerializeTx(&tx)
if (err != nil) != tt.wantErr {
t.Errorf("SpendTx.RLP() error = %v, wantErr %v", err, tt.wantErr)
Expand All @@ -88,6 +91,71 @@ func TestSpendTx_EncodeRLP(t *testing.T) {
})
}
}

func TestSpendTx_DecodeRLP(t *testing.T) {
type args struct {
rlpBytes []byte
}
tests := []struct {
name string
wantTx SpendTx
args args
wantErr bool
}{
{
args: args{
// tx_+FYMAaEBzqet5HDJ+Z2dTkAIgKhvHUm7REti8Rqeu2S7z+tz/vOhAR8To7CL8AFABmKmi2nYdfeAPOxMCGR/btXYTHiXvVCjCgoKAYtIZWxsbyBXb3JsZPSZjdM=
// [12] [1] [1 206 167 173 228 112 201 249 157 157 78 64 8 128 168 111 29 73 187 68 75 98 241 26 158 187 100 187 207 235 115 254 243] [1 31 19 163 176 139 240 1 64 6 98 166 139 105 216 117 247 128 60 236 76 8 100 127 110 213 216 76 120 151 189 80 163] [10] [10] [10] [1] [72 101 108 108 111 32 87 111 114 108 100]]
rlpBytes: []byte{248, 86, 12, 1, 161, 1, 206, 167, 173, 228, 112, 201, 249, 157, 157, 78, 64, 8, 128, 168, 111, 29, 73, 187, 68, 75, 98, 241, 26, 158, 187, 100, 187, 207, 235, 115, 254, 243, 161, 1, 31, 19, 163, 176, 139, 240, 1, 64, 6, 98, 166, 139, 105, 216, 117, 247, 128, 60, 236, 76, 8, 100, 127, 110, 213, 216, 76, 120, 151, 189, 80, 163, 10, 10, 10, 1, 139, 72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100},
},
name: "Spend 10, Fee 10, Hello World",
wantTx: SpendTx{
SenderID: "ak_2a1j2Mk9YSmC1gioUq4PWRm3bsv887MbuRVwyv4KaUGoR1eiKi",
RecipientID: "ak_Egp9yVdpxmvAfQ7vsXGvpnyfNq71msbdUpkMNYGTeTe8kPL3v",
Amount: *utils.NewIntFromUint64(10),
Fee: *utils.NewIntFromUint64(10),
Payload: []byte("Hello World"),
TTL: uint64(10),
Nonce: uint64(1),
},
wantErr: false,
},
{
args: args{
// tx_+FYMAaEBzqet5HDJ+Z2dTkAIgKhvHUm7REti8Rqeu2S7z+tz/vOhAR8To7CL8AFABmKmi2nYdfeAPOxMCGR/btXYTHiXvVCjAAoKAYtIZWxsbyBXb3JsZICI5/w=
// [[12] [1] [1 206 167 173 228 112 201 249 157 157 78 64 8 128 168 111 29 73 187 68 75 98 241 26 158 187 100 187 207 235 115 254 243] [1 31 19 163 176 139 240 1 64 6 98 166 139 105 216 117 247 128 60 236 76 8 100 127 110 213 216 76 120 151 189 80 163] [0] [10] [10] [1] [72 101 108 108 111 32 87 111 114 108 100]]
rlpBytes: []byte{248, 86, 12, 1, 161, 1, 206, 167, 173, 228, 112, 201, 249, 157, 157, 78, 64, 8, 128, 168, 111, 29, 73, 187, 68, 75, 98, 241, 26, 158, 187, 100, 187, 207, 235, 115, 254, 243, 161, 1, 31, 19, 163, 176, 139, 240, 1, 64, 6, 98, 166, 139, 105, 216, 117, 247, 128, 60, 236, 76, 8, 100, 127, 110, 213, 216, 76, 120, 151, 189, 80, 163, 0, 10, 10, 1, 139, 72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100},
},
name: "Spend 0, Fee 10, Hello World (check correct RLP deserialization of 0)",
wantTx: SpendTx{
SenderID: "ak_2a1j2Mk9YSmC1gioUq4PWRm3bsv887MbuRVwyv4KaUGoR1eiKi",
RecipientID: "ak_Egp9yVdpxmvAfQ7vsXGvpnyfNq71msbdUpkMNYGTeTe8kPL3v",
Amount: *utils.NewIntFromUint64(0),
Fee: *utils.NewIntFromUint64(10),
Payload: []byte("Hello World"),
TTL: uint64(10),
Nonce: uint64(1),
},
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
gotTx := SpendTx{}
b := &bytes.Buffer{}
b.Write(tt.args.rlpBytes)

err := rlp.Decode(b, &gotTx)
if err != nil {
t.Error(err)
}
if !(gotTx.Equal(&tt.wantTx)) {
t.Errorf("Deserialization resulted in different structs: got %+v, want %+v", gotTx, tt.wantTx)
}
})
}
}

func TestNamePointer_EncodeRLP(t *testing.T) {
type fields struct {
ID string
Expand Down

0 comments on commit b5c3812

Please sign in to comment.