Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

txnbuild: add AddSignatureDecorated #3640

Merged
merged 5 commits into from
May 28, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions txnbuild/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ file. This project adheres to [Semantic Versioning](http://semver.org/).
### New features

* Add `SequenceNumber` function to `Transaction`.
* Add `AddSignatureDecorated` function to `Transaction`.

### Bug Fix

Expand Down
18 changes: 18 additions & 0 deletions txnbuild/transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,13 @@ func concatSignatures(
return extended, nil
}

func concatSignatureDecorated(e xdr.TransactionEnvelope, signatures []xdr.DecoratedSignature, newSignatures []xdr.DecoratedSignature) ([]xdr.DecoratedSignature, error) {
extended := make([]xdr.DecoratedSignature, len(signatures)+len(newSignatures))
copy(extended, signatures)
copy(extended[len(signatures):], newSignatures)
return extended, nil
}

func concatSignatureBase64(e xdr.TransactionEnvelope, signatures []xdr.DecoratedSignature, networkStr, publicKey, signature string) ([]xdr.DecoratedSignature, error) {
if signature == "" {
return nil, errors.New("signature not presented")
Expand Down Expand Up @@ -305,6 +312,17 @@ func (t *Transaction) SignHashX(preimage []byte) (*Transaction, error) {
return t.clone(extendedSignatures), nil
}

// AddSignatureDecorated returns a new Transaction instance which extends the current instance
// with an additional decorated signature(s).
func (t *Transaction) AddSignatureDecorated(signature ...xdr.DecoratedSignature) (*Transaction, error) {
extendedSignatures, err := concatSignatureDecorated(t.envelope, t.Signatures(), signature)
if err != nil {
return nil, err
}

return t.clone(extendedSignatures), nil
}

// AddSignatureBase64 returns a new Transaction instance which extends the current instance
// with an additional signature derived from the given base64-encoded signature.
func (t *Transaction) AddSignatureBase64(network, publicKey, signature string) (*Transaction, error) {
Expand Down
107 changes: 107 additions & 0 deletions txnbuild/transaction_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1577,6 +1577,113 @@ func TestSignWithSecretKey(t *testing.T) {
assert.Equal(t, expected, actual, "base64 xdr should match")
}

func TestAddSignatureDecorated(t *testing.T) {
kp0 := newKeypair0()
kp1 := newKeypair1()
txSource := NewSimpleAccount(kp0.Address(), int64(9605939170639897))
tx1Source := NewSimpleAccount(kp0.Address(), int64(9605939170639897))
createAccount := CreateAccount{
Destination: "GCCOBXW2XQNUSL467IEILE6MMCNRR66SSVL4YQADUNYYNUVREF3FIV2Z",
Amount: "10",
SourceAccount: kp1.Address(),
}

expected, err := newSignedTransaction(
TransactionParams{
SourceAccount: &txSource,
IncrementSequenceNum: true,
Operations: []Operation{&createAccount},
BaseFee: MinBaseFee,
Timebounds: NewInfiniteTimeout(),
},
network.TestNetworkPassphrase,
kp0, kp1,
)
assert.NoError(t, err)

tx1, err := NewTransaction(
TransactionParams{
SourceAccount: &tx1Source,
IncrementSequenceNum: true,
Operations: []Operation{&createAccount},
BaseFee: MinBaseFee,
Timebounds: NewInfiniteTimeout(),
},
)
assert.NoError(t, err)

// Same if signatures added separately.
{
var tx1sigs1 *Transaction
tx1sigs1, err = tx1.AddSignatureDecorated(
xdr.DecoratedSignature{
Hint: kp0.Hint(),
Signature: func() xdr.Signature {
var sigBytes []byte
sigBytes, err = base64.StdEncoding.DecodeString("TVogR6tbrWLnOc1BsP/j+Qrxpja2NWNgeRIwujECYscRdMG7AMtnb3dkCT7sqlbSM0TTzlRh7G+BcVocYBtqBw==")
if err != nil {
require.NoError(t, err)
}
return xdr.Signature(sigBytes)
}(),
},
)
assert.NoError(t, err)
tx1sigs1, err = tx1sigs1.AddSignatureDecorated(
xdr.DecoratedSignature{
Hint: kp1.Hint(),
Signature: func() xdr.Signature {
var sigBytes []byte
sigBytes, err = base64.StdEncoding.DecodeString("Iy77JteoW/FbeiuViZpgTyvrHP4BnBOeyVOjrdb5O/MpEMwcSlYXAkCBqPt4tBDil4jIcDDLhm7TsN6aUBkIBg==")
if err != nil {
require.NoError(t, err)
}
return xdr.Signature(sigBytes)
}(),
},
)
assert.NoError(t, err)
var actual string
actual, err = tx1sigs1.Base64()
assert.NoError(t, err)
assert.Equal(t, expected, actual, "base64 xdr should match")
}

// Same if signatures added together.
{
var tx1sigs2 *Transaction
tx1sigs2, err = tx1.AddSignatureDecorated(
xdr.DecoratedSignature{
Hint: kp0.Hint(),
Signature: func() xdr.Signature {
var sigBytes []byte
sigBytes, err = base64.StdEncoding.DecodeString("TVogR6tbrWLnOc1BsP/j+Qrxpja2NWNgeRIwujECYscRdMG7AMtnb3dkCT7sqlbSM0TTzlRh7G+BcVocYBtqBw==")
if err != nil {
require.NoError(t, err)
}
return xdr.Signature(sigBytes)
}(),
},
xdr.DecoratedSignature{
Hint: kp1.Hint(),
Signature: func() xdr.Signature {
var sigBytes []byte
sigBytes, err = base64.StdEncoding.DecodeString("Iy77JteoW/FbeiuViZpgTyvrHP4BnBOeyVOjrdb5O/MpEMwcSlYXAkCBqPt4tBDil4jIcDDLhm7TsN6aUBkIBg==")
if err != nil {
require.NoError(t, err)
}
return xdr.Signature(sigBytes)
}(),
},
)
assert.NoError(t, err)
var actual string
actual, err = tx1sigs2.Base64()
assert.NoError(t, err)
assert.Equal(t, expected, actual, "base64 xdr should match")
}
}

func TestAddSignatureBase64(t *testing.T) {
kp0 := newKeypair0()
kp1 := newKeypair1()
Expand Down