Skip to content

Commit

Permalink
Add ToXDR functions which do not return errors (#2651)
Browse files Browse the repository at this point in the history
Add ToXDR() functions for Transaction and FeeBumpTransaction instances which return xdr transaction envelopes without errors.
  • Loading branch information
tamirms authored Jun 3, 2020
1 parent f1e7c4a commit 911cb5f
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 13 deletions.
1 change: 1 addition & 0 deletions txnbuild/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ file. This project adheres to [Semantic Versioning](http://semver.org/).
## Unreleased

* `txnbuild` now generates V1 transaction envelopes which are only supported by Protocol 13 ([#2640](https://github.com/stellar/go/pull/2640))
* Add `ToXDR()` functions for `Transaction` and `FeeBumpTransaction` instances which return xdr transaction envelopes without errors ([#2651](https://github.com/stellar/go/pull/2651))

## [v3.1.0](https://github.com/stellar/go/releases/tag/horizonclient-v3.1.0) - 2020-05-14

Expand Down
43 changes: 30 additions & 13 deletions txnbuild/signers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -436,12 +436,15 @@ func TestSetOptionsMultSigners(t *testing.T) {
assert.Equal(t, expected, received, "Base 64 XDR should match")
}

type SignatureList interface {
type transactionCommon interface {
Signatures() []xdr.DecoratedSignature
Hash(networkStr string) ([32]byte, error)
Base64() (string, error)
TxEnvelope() (xdr.TransactionEnvelope, error)
ToXDR() xdr.TransactionEnvelope
}

func verifySignatures(t *testing.T, tx SignatureList, signers ...*keypair.Full) {
func verifySignatures(t *testing.T, tx transactionCommon, signers ...*keypair.Full) {
assert.Len(t, tx.Signatures(), len(signers))

hash, err := tx.Hash(network.TestNetworkPassphrase)
Expand All @@ -452,6 +455,25 @@ func verifySignatures(t *testing.T, tx SignatureList, signers ...*keypair.Full)
}
}

func assertBase64(t *testing.T, tx transactionCommon) string {
base64, err := tx.Base64()
assert.NoError(t, err)

envCopy, err := tx.TxEnvelope()
assert.NoError(t, err)
envCopyBase64, err := xdr.MarshalBase64(envCopy)
assert.NoError(t, err)

envRef := tx.ToXDR()
envRefBase64, err := xdr.MarshalBase64(envRef)
assert.NoError(t, err)

assert.Equal(t, base64, envCopyBase64)
assert.Equal(t, base64, envRefBase64)

return base64
}

func TestSigningImmutability(t *testing.T) {
kp0, kp1, kp2 := newKeypair0(), newKeypair1(), newKeypair2()

Expand All @@ -466,18 +488,15 @@ func TestSigningImmutability(t *testing.T) {
assert.NoError(t, err)
root, err = root.Sign(network.TestNetworkPassphrase, kp0)
assert.NoError(t, err)
rootB64, err := root.Base64()
assert.NoError(t, err)
rootB64 := assertBase64(t, root)

left, err := root.Sign(network.TestNetworkPassphrase, kp1)
assert.NoError(t, err)
leftB64, err := left.Base64()
assert.NoError(t, err)
leftB64 := assertBase64(t, left)

right, err := root.Sign(network.TestNetworkPassphrase, kp2)
assert.NoError(t, err)
rightB64, err := right.Base64()
assert.NoError(t, err)
rightB64 := assertBase64(t, right)

expectedRootB64, err := newSignedTransaction(
params, network.TestNetworkPassphrase, kp0,
Expand Down Expand Up @@ -521,18 +540,16 @@ func TestFeeBumpSigningImmutability(t *testing.T) {
root, err := NewFeeBumpTransaction(params)
assert.NoError(t, err)
root, err = root.Sign(network.TestNetworkPassphrase, kp1)
rootB64, err := root.Base64()
assert.NoError(t, err)
rootB64 := assertBase64(t, root)

left, err := root.Sign(network.TestNetworkPassphrase, kp0)
assert.NoError(t, err)
leftB64, err := left.Base64()
assert.NoError(t, err)
leftB64 := assertBase64(t, left)

right, err := root.Sign(network.TestNetworkPassphrase, kp2)
assert.NoError(t, err)
rightB64, err := right.Base64()
assert.NoError(t, err)
rightB64 := assertBase64(t, right)

expectedRootB64, err := newSignedFeeBumpTransaction(
params, network.TestNetworkPassphrase, kp1,
Expand Down
32 changes: 32 additions & 0 deletions txnbuild/transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,23 @@ func (t *Transaction) TxEnvelope() (xdr.TransactionEnvelope, error) {
return cloneEnvelope(t.envelope, t.signatures)
}

// ToXDR is like TxEnvelope except that the transaction envelope returned by ToXDR
// should not be modified because any changes applied to the transaction envelope may
// affect the internals of the Transaction instance.
func (t *Transaction) ToXDR() xdr.TransactionEnvelope {
env := t.envelope
switch env.Type {
case xdr.EnvelopeTypeEnvelopeTypeTx:
env.V1.Signatures = t.signatures
case xdr.EnvelopeTypeEnvelopeTypeTxV0:
env.V0.Signatures = t.signatures
default:
panic("invalid transaction type: " + env.Type.String())
}

return env
}

// MarshalBinary returns the binary XDR representation of the transaction envelope.
func (t *Transaction) MarshalBinary() ([]byte, error) {
return marshallBinary(t.envelope, t.signatures)
Expand Down Expand Up @@ -432,6 +449,21 @@ func (t *FeeBumpTransaction) TxEnvelope() (xdr.TransactionEnvelope, error) {
return cloneEnvelope(t.envelope, t.signatures)
}

// ToXDR is like TxEnvelope except that the transaction envelope returned by ToXDR
// should not be modified because any changes applied to the transaction envelope may
// affect the internals of the FeeBumpTransaction instance.
func (t *FeeBumpTransaction) ToXDR() xdr.TransactionEnvelope {
env := t.envelope
switch env.Type {
case xdr.EnvelopeTypeEnvelopeTypeTxFeeBump:
env.FeeBump.Signatures = t.signatures
default:
panic("invalid transaction type: " + env.Type.String())
}

return env
}

// MarshalBinary returns the binary XDR representation of the transaction envelope.
func (t *FeeBumpTransaction) MarshalBinary() ([]byte, error) {
return marshallBinary(t.envelope, t.signatures)
Expand Down

0 comments on commit 911cb5f

Please sign in to comment.