mirror of
https://github.com/Xahau/xahau.js.git
synced 2025-11-19 19:55:51 +00:00
Autofill LastLedgerSequence for multisigned transactions
This commit is contained in:
@@ -45,6 +45,7 @@ function Transaction(remote) {
|
||||
? this.remote.automatic_resubmission
|
||||
: true;
|
||||
this._maxFee = remoteExists ? this.remote.max_fee : undefined;
|
||||
this._lastLedgerOffset = remoteExists ? this.remote.last_ledger_offset : 3;
|
||||
this.state = 'unsubmitted';
|
||||
this.finalized = false;
|
||||
this.previousSigningHash = undefined;
|
||||
@@ -582,19 +583,30 @@ Transaction.prototype.clientID = function(id) {
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Set LastLedgerSequence as the absolute last ledger sequence the transaction
|
||||
* is valid for. LastLedgerSequence is set automatically if not set using this
|
||||
* method
|
||||
*
|
||||
* @param {Number} ledger index
|
||||
*/
|
||||
Transaction.prototype.setLastLedgerSequenceOffset = function(offset) {
|
||||
this._lastLedgerOffset = offset;
|
||||
};
|
||||
|
||||
Transaction.prototype.setLastLedgerSequence =
|
||||
Transaction.prototype.getLastLedgerSequenceOffset = function() {
|
||||
return this._lastLedgerOffset;
|
||||
};
|
||||
|
||||
Transaction.prototype.lastLedger =
|
||||
Transaction.prototype.setLastLedger =
|
||||
Transaction.prototype.lastLedger = function(sequence) {
|
||||
Transaction.prototype.setLastLedgerSequence = function(sequence) {
|
||||
if (!_.isUndefined(sequence)) {
|
||||
this._setUInt32('LastLedgerSequence', sequence);
|
||||
} else {
|
||||
// Autofill LastLedgerSequence
|
||||
assert(this.remote, 'Unable to set LastLedgerSequence, missing Remote');
|
||||
|
||||
this._setUInt32('LastLedgerSequence',
|
||||
this.remote.getLedgerSequence() + 1
|
||||
+ this.getLastLedgerSequenceOffset());
|
||||
}
|
||||
|
||||
this._setLastLedger = true;
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
@@ -1479,7 +1491,7 @@ Transaction.prototype.summary = function() {
|
||||
submissionAttempts: this.attempts,
|
||||
submitIndex: this.submitIndex,
|
||||
initialSubmitIndex: this.initialSubmitIndex,
|
||||
lastLedgerSequence: this.lastLedgerSequence,
|
||||
lastLedgerSequence: this.tx_json.LastLedgerSequence,
|
||||
state: this.state,
|
||||
finalized: this.finalized
|
||||
};
|
||||
@@ -1616,30 +1628,44 @@ Transaction.prototype.setSigners = function(signers) {
|
||||
Transaction.prototype.addMultiSigner = function(signer) {
|
||||
assert(UInt160.is_valid(signer.Account), 'Signer must have a valid Account');
|
||||
|
||||
if (_.isUndefined(this.multi_signers)) {
|
||||
this.multi_signers = [];
|
||||
if (_.isUndefined(this.tx_json.Signers)) {
|
||||
this.tx_json.Signers = [];
|
||||
}
|
||||
|
||||
this.multi_signers.push({Signer: signer});
|
||||
this.tx_json.Signers.push({Signer: signer});
|
||||
|
||||
this.multi_signers.sort((a, b) => {
|
||||
this.tx_json.Signers.sort((a, b) => {
|
||||
return UInt160.from_json(a.Signer.Account)
|
||||
.cmp(UInt160.from_json(b.Signer.Account));
|
||||
});
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
Transaction.prototype.hasMultiSigners = function() {
|
||||
return !_.isEmpty(this.multi_signers);
|
||||
return !_.isEmpty(this.tx_json.Signers);
|
||||
};
|
||||
|
||||
Transaction.prototype.getMultiSigners = function() {
|
||||
return this.multi_signers;
|
||||
return this.tx_json.Signers;
|
||||
};
|
||||
|
||||
Transaction.prototype.getMultiSigningJson = function() {
|
||||
assert(this.tx_json.Sequence, 'Sequence must be set before multi-signing');
|
||||
assert(this.tx_json.Fee, 'Fee must be set before multi-signing');
|
||||
|
||||
const signingTx = Transaction.from_json(this.tx_json);
|
||||
if (_.isUndefined(this.tx_json.LastLedgerSequence)) {
|
||||
// Auto-fill LastLedgerSequence
|
||||
this.setLastLedgerSequence();
|
||||
}
|
||||
|
||||
const cleanedJson = _.omit(this.tx_json, [
|
||||
'SigningPubKey',
|
||||
'Signers',
|
||||
'TxnSignature'
|
||||
]);
|
||||
|
||||
const signingTx = Transaction.from_json(cleanedJson);
|
||||
signingTx.remote = this.remote;
|
||||
signingTx.setSigningPubKey('');
|
||||
signingTx.setCanonicalFlag();
|
||||
|
||||
@@ -27,7 +27,6 @@ function TransactionManager(account) {
|
||||
this._maxFee = this._remote.max_fee;
|
||||
this._maxAttempts = this._remote.max_attempts;
|
||||
this._submissionTimeout = this._remote.submission_timeout;
|
||||
this._lastLedgerOffset = this._remote.last_ledger_offset;
|
||||
this._pending = new PendingQueue();
|
||||
|
||||
this._account.on('transaction-outbound', function(res) {
|
||||
@@ -521,17 +520,6 @@ TransactionManager.prototype._resubmit = function(ledgers_, pending_) {
|
||||
TransactionManager.prototype._prepareRequest = function(tx) {
|
||||
const submitRequest = this._remote.requestSubmit();
|
||||
|
||||
if (tx.hasMultiSigners()) {
|
||||
tx.setSigningPubKey('');
|
||||
|
||||
if (this._remote.local_signing) {
|
||||
tx.setSigners(tx.getMultiSigners());
|
||||
} else {
|
||||
submitRequest.message.command = 'submit_multisigned';
|
||||
submitRequest.message.Signers = tx.getMultiSigners();
|
||||
}
|
||||
}
|
||||
|
||||
if (this._remote.local_signing) {
|
||||
tx.sign();
|
||||
|
||||
@@ -541,6 +529,10 @@ TransactionManager.prototype._prepareRequest = function(tx) {
|
||||
const hash = tx.hash(null, null, serialized);
|
||||
tx.addId(hash);
|
||||
} else {
|
||||
if (tx.hasMultiSigners()) {
|
||||
submitRequest.message.command = 'submit_multisigned';
|
||||
}
|
||||
|
||||
// ND: `build_path` is completely ignored when doing local signing as
|
||||
// `Paths` is a component of the signed blob, the `tx_blob` is signed,
|
||||
// sealed and delivered, and the txn unmodified.
|
||||
@@ -580,6 +572,11 @@ TransactionManager.prototype._request = function(tx) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (Number(tx.tx_json.Fee) > tx._maxFee) {
|
||||
tx.emit('error', new RippleError('tejMaxFeeExceeded'));
|
||||
return;
|
||||
}
|
||||
|
||||
if (remote.trace) {
|
||||
log.info('submit transaction:', tx.tx_json);
|
||||
}
|
||||
@@ -684,24 +681,12 @@ TransactionManager.prototype._request = function(tx) {
|
||||
}
|
||||
}
|
||||
|
||||
tx.submitIndex = this._remote._ledger_current_index;
|
||||
tx.submitIndex = this._remote.getLedgerSequence() + 1;
|
||||
|
||||
if (tx.attempts === 0) {
|
||||
tx.initialSubmitIndex = tx.submitIndex;
|
||||
}
|
||||
|
||||
if (!tx._setLastLedger && !tx.hasMultiSigners()) {
|
||||
// Honor LastLedgerSequence set with tx.lastLedger()
|
||||
tx.tx_json.LastLedgerSequence = tx.initialSubmitIndex
|
||||
+ this._lastLedgerOffset;
|
||||
}
|
||||
|
||||
tx.lastLedgerSequence = tx.tx_json.LastLedgerSequence;
|
||||
|
||||
if (remote.local_signing) {
|
||||
tx.sign();
|
||||
}
|
||||
|
||||
const submitRequest = this._prepareRequest(tx);
|
||||
submitRequest.once('error', submitted);
|
||||
submitRequest.once('success', submitted);
|
||||
@@ -743,8 +728,13 @@ TransactionManager.prototype.submit = function(tx) {
|
||||
tx.setSequence(this._nextSequence++);
|
||||
}
|
||||
|
||||
if (_.isUndefined(tx.tx_json.LastLedgerSequence)) {
|
||||
tx.setLastLedgerSequence();
|
||||
}
|
||||
|
||||
if (tx.hasMultiSigners()) {
|
||||
tx.setResubmittable(false);
|
||||
tx.setSigningPubKey('');
|
||||
}
|
||||
|
||||
tx.once('cleanup', function() {
|
||||
|
||||
@@ -518,7 +518,9 @@ describe('TransactionManager', function() {
|
||||
break;
|
||||
}
|
||||
});
|
||||
/* eslint-disable no-unused-vars */
|
||||
rippled.once('request_submit', function(m, req) {
|
||||
/* eslint-enable no-unused-vars */
|
||||
req.sendJSON(lodash.extend({}, LEDGER, {
|
||||
ledger_index: transaction.tx_json.LastLedgerSequence + 1
|
||||
}));
|
||||
@@ -574,7 +576,9 @@ describe('TransactionManager', function() {
|
||||
req.sendResponse(SUBMIT_TEF_RESPONSE, {id: m.id});
|
||||
});
|
||||
|
||||
/* eslint-disable no-unused-vars */
|
||||
rippled.once('request_submit', function(m, req) {
|
||||
/* eslint-enable no-unused-vars */
|
||||
transaction.once('resubmitted', function() {
|
||||
receivedResubmitted = true;
|
||||
req.sendJSON(lodash.extend({}, LEDGER, {
|
||||
@@ -634,7 +638,9 @@ describe('TransactionManager', function() {
|
||||
req.sendResponse(SUBMIT_TEL_RESPONSE, {id: m.id});
|
||||
});
|
||||
|
||||
/* eslint-disable no-unused-vars */
|
||||
rippled.once('request_submit', function(m, req) {
|
||||
/* eslint-enable no-unused-vars */
|
||||
transaction.once('resubmitted', function() {
|
||||
receivedResubmitted = true;
|
||||
req.sendJSON(lodash.extend({}, LEDGER, {
|
||||
@@ -690,7 +696,7 @@ describe('TransactionManager', function() {
|
||||
assert.strictEqual(summary.submissionAttempts, 0);
|
||||
assert.strictEqual(summary.submitIndex, undefined);
|
||||
assert.strictEqual(summary.initialSubmitIndex, undefined);
|
||||
assert.strictEqual(summary.lastLedgerSequence, undefined);
|
||||
assert.strictEqual(summary.lastLedgerSequence, remote.getLedgerSequence() + 1 + Remote.DEFAULTS.last_ledger_offset);
|
||||
assert.strictEqual(summary.state, 'failed');
|
||||
assert.strictEqual(summary.finalized, true);
|
||||
assert.deepEqual(summary.result, {
|
||||
@@ -799,7 +805,9 @@ describe('TransactionManager', function() {
|
||||
req.sendResponse(SUBMIT_TEL_RESPONSE, {id: m.id});
|
||||
});
|
||||
|
||||
/* eslint-disable no-unused-vars */
|
||||
rippled.once('request_submit', function(m, req) {
|
||||
/* eslint-enable no-unused-vars */
|
||||
transaction.once('resubmitted', function() {
|
||||
receivedResubmitted = true;
|
||||
});
|
||||
@@ -857,6 +865,7 @@ describe('TransactionManager', function() {
|
||||
receivedSubmitted = true;
|
||||
});
|
||||
|
||||
/* eslint-disable no-unused-vars */
|
||||
rippled.on('request_submit', function(m, req) {
|
||||
assert.strictEqual(m.tx_blob, SerializedObject.from_json(
|
||||
transaction.tx_json).to_hex());
|
||||
@@ -867,7 +876,9 @@ describe('TransactionManager', function() {
|
||||
req.sendResponse(SUBMIT_TOO_BUSY_ERROR, {id: m.id});
|
||||
});
|
||||
|
||||
/* eslint-disable no-unused-vars */
|
||||
rippled.once('request_submit', function(m, req) {
|
||||
/* eslint-enable no-unused-vars */
|
||||
transaction.once('resubmitted', function() {
|
||||
receivedResubmitted = true;
|
||||
req.sendJSON(lodash.extend({}, LEDGER, {
|
||||
|
||||
@@ -983,9 +983,6 @@ describe('Transaction', function() {
|
||||
it('Set LastLedgerSequence', function() {
|
||||
const transaction = new Transaction();
|
||||
|
||||
assert.throws(function() {
|
||||
transaction.lastLedger('a');
|
||||
}, /Error: LastLedgerSequence must be a valid UInt32/);
|
||||
assert.throws(function() {
|
||||
transaction.setLastLedgerSequence('a');
|
||||
}, /Error: LastLedgerSequence must be a valid UInt32/);
|
||||
@@ -1945,6 +1942,8 @@ describe('Transaction', function() {
|
||||
|
||||
it('Submit transaction', function(done) {
|
||||
const remote = new Remote();
|
||||
remote._ledger_current_index = 1;
|
||||
|
||||
const transaction = new Transaction(remote).accountSet('r36xtKNKR43SeXnGn7kN4r4JdQzcrkqpWe');
|
||||
|
||||
assert.strictEqual(transaction.callback, undefined);
|
||||
@@ -1989,6 +1988,8 @@ describe('Transaction', function() {
|
||||
it('Submit transaction - submission error', function(done) {
|
||||
const remote = new Remote();
|
||||
|
||||
remote._ledger_current_index = 1;
|
||||
|
||||
const transaction = new Transaction(remote).accountSet('r36xtKNKR43SeXnGn7kN4r4JdQzcrkqpWe');
|
||||
|
||||
const account = remote.addAccount('r36xtKNKR43SeXnGn7kN4r4JdQzcrkqpWe');
|
||||
@@ -2107,82 +2108,6 @@ describe('Transaction', function() {
|
||||
});
|
||||
});
|
||||
|
||||
it('Add multisigner', function() {
|
||||
const transaction = new Transaction();
|
||||
const s1 = {
|
||||
Account: 'rPMh7Pi9ct699iZUTWaytJUoHcJ7cgyziK',
|
||||
TxnSignature: '304402203020865BDC995431325C371E6A3CE89BFC40597D9CFAF77DBB16E9D159824EA402203645A6462A6DCEC7B5D0811882DC54CEA66258A227A2762BE6EFCD9EB62C27BF',
|
||||
SigningPubKey: '02691AC5AE1C4C333AE5DF8A93BDC495F0EEBFC6DB0DA7EB6EF808F3AFC006E3FE'
|
||||
};
|
||||
const s2 = {
|
||||
Account: 'rH4KEcG9dEwGwpn6AyoWK9cZPLL4RLSmWW',
|
||||
TxnSignature: '30450221009C84E455DC199A7DB4B800D68C92269D60972E8850AFC0D50B1AE6B08BBB02EA02206FA93A560BE96844DF7D96D07F6400EF9534A32FBA352DD10E855DA8923A3AF8',
|
||||
SigningPubKey: '028949021029D5CC87E78BCF053AFEC0CAFD15108EC119EAAFEC466F5C095407BF'
|
||||
};
|
||||
|
||||
transaction.addMultiSigner(s1);
|
||||
transaction.addMultiSigner(s2);
|
||||
|
||||
assert.deepEqual(transaction.getMultiSigners(), [
|
||||
{Signer: s2}, {Signer: s1}]);
|
||||
});
|
||||
|
||||
it('Get multisign data', function() {
|
||||
const transaction = Transaction.from_json({
|
||||
Account: 'rG1QQv2nh2gr7RCZ1P8YYcBUKCCN633jCn',
|
||||
Sequence: 1,
|
||||
Fee: '100',
|
||||
TransactionType: 'AccountSet',
|
||||
Flags: 0
|
||||
});
|
||||
|
||||
transaction.setSigningPubKey('');
|
||||
|
||||
const a1 = 'rPMh7Pi9ct699iZUTWaytJUoHcJ7cgyziK';
|
||||
const d1 = transaction.multiSigningData(a1);
|
||||
|
||||
const tbytes = ripple.SerializedObject.from_json(
|
||||
lodash.merge(transaction.tx_json, {SigningPubKey: ''})).buffer;
|
||||
const abytes = ripple.UInt160.from_json(a1).to_bytes();
|
||||
const prefix = require('ripple-lib')._test.HashPrefixes.HASH_TX_MULTISIGN_BYTES;
|
||||
|
||||
assert.deepEqual(d1.buffer, prefix.concat(tbytes, abytes));
|
||||
});
|
||||
|
||||
it('Multisign', function() {
|
||||
const transaction = Transaction.from_json({
|
||||
Account: 'rG1QQv2nh2gr7RCZ1P8YYcBUKCCN633jCn',
|
||||
Sequence: 1,
|
||||
Fee: '100',
|
||||
TransactionType: 'AccountSet',
|
||||
Flags: 0
|
||||
});
|
||||
|
||||
const multiSigningJson = transaction.getMultiSigningJson();
|
||||
const t1 = Transaction.from_json(multiSigningJson);
|
||||
|
||||
const a1 = 'rPMh7Pi9ct699iZUTWaytJUoHcJ7cgyziK';
|
||||
const a2 = 'rH4KEcG9dEwGwpn6AyoWK9cZPLL4RLSmWW';
|
||||
|
||||
const s1 = t1.multiSign(a1, 'alice');
|
||||
assert.strictEqual(s1.Account, a1);
|
||||
assert.strictEqual(s1.SigningPubKey, '0388935426E0D08083314842EDFBB2D517BD47699F9A4527318A8E10468C97C052');
|
||||
assert.strictEqual(s1.TxnSignature, '30440220611256E46B2946152695FFEF34D5C71BB3AE569C3D919A270BFBCA9ADF260D9202202FAE24FC8A575FE3265A6D7CFA596094A7950E0011706431A11C2A9ABEF60B3B');
|
||||
|
||||
const s2 = t1.multiSign(a2, 'bob');
|
||||
assert.strictEqual(s2.Account, a2);
|
||||
assert.strictEqual(s2.SigningPubKey, '02691AC5AE1C4C333AE5DF8A93BDC495F0EEBFC6DB0DA7EB6EF808F3AFC006E3FE');
|
||||
assert.strictEqual(s2.TxnSignature, '3044022067F769BE0A4CC2B4F26E7B52B366F861FED02DA0F564F98B44009C8181A9655702206D882919139DF8E9D7F2FC1DD54D8B4FEAC40203349AE21519FD388925A4DE83');
|
||||
|
||||
transaction.addMultiSigner(s1);
|
||||
transaction.addMultiSigner(s2);
|
||||
|
||||
assert.deepEqual(transaction.getMultiSigners(), [
|
||||
{Signer: s2},
|
||||
{Signer: s1}
|
||||
]);
|
||||
});
|
||||
|
||||
it('Construct SuspendedPaymentCreate transaction', function() {
|
||||
const transaction = new Transaction().suspendedPaymentCreate({
|
||||
account: 'rsLEU1TPdCJPPysqhWYw9jD97xtG5WqSJm',
|
||||
@@ -2294,4 +2219,101 @@ describe('Transaction', function() {
|
||||
OfferSequence: 1234
|
||||
});
|
||||
});
|
||||
|
||||
it('Add multisigner', function() {
|
||||
const transaction = new Transaction();
|
||||
const s1 = {
|
||||
Account: 'rPMh7Pi9ct699iZUTWaytJUoHcJ7cgyziK',
|
||||
TxnSignature: '304402203020865BDC995431325C371E6A3CE89BFC40597D9CFAF77DBB16E9D159824EA402203645A6462A6DCEC7B5D0811882DC54CEA66258A227A2762BE6EFCD9EB62C27BF',
|
||||
SigningPubKey: '02691AC5AE1C4C333AE5DF8A93BDC495F0EEBFC6DB0DA7EB6EF808F3AFC006E3FE'
|
||||
};
|
||||
const s2 = {
|
||||
Account: 'rH4KEcG9dEwGwpn6AyoWK9cZPLL4RLSmWW',
|
||||
TxnSignature: '30450221009C84E455DC199A7DB4B800D68C92269D60972E8850AFC0D50B1AE6B08BBB02EA02206FA93A560BE96844DF7D96D07F6400EF9534A32FBA352DD10E855DA8923A3AF8',
|
||||
SigningPubKey: '028949021029D5CC87E78BCF053AFEC0CAFD15108EC119EAAFEC466F5C095407BF'
|
||||
};
|
||||
|
||||
transaction.addMultiSigner(s1);
|
||||
transaction.addMultiSigner(s2);
|
||||
|
||||
assert.deepEqual(transaction.getMultiSigners(), [
|
||||
{Signer: s2}, {Signer: s1}]);
|
||||
});
|
||||
|
||||
it('Get multisign data', function() {
|
||||
const transaction = Transaction.from_json({
|
||||
Account: 'rG1QQv2nh2gr7RCZ1P8YYcBUKCCN633jCn',
|
||||
Sequence: 1,
|
||||
Fee: '100',
|
||||
TransactionType: 'AccountSet',
|
||||
Flags: 0
|
||||
});
|
||||
|
||||
transaction.setSigningPubKey('');
|
||||
|
||||
const a1 = 'rPMh7Pi9ct699iZUTWaytJUoHcJ7cgyziK';
|
||||
const d1 = transaction.multiSigningData(a1);
|
||||
|
||||
const tbytes = ripple.SerializedObject.from_json(
|
||||
lodash.merge(transaction.tx_json, {SigningPubKey: ''})).buffer;
|
||||
const abytes = ripple.UInt160.from_json(a1).to_bytes();
|
||||
const prefix = require('ripple-lib')._test.HashPrefixes.HASH_TX_MULTISIGN_BYTES;
|
||||
|
||||
assert.deepEqual(d1.buffer, prefix.concat(tbytes, abytes));
|
||||
});
|
||||
|
||||
it('Multisign', function() {
|
||||
const transaction = Transaction.from_json({
|
||||
Account: 'rG1QQv2nh2gr7RCZ1P8YYcBUKCCN633jCn',
|
||||
Sequence: 1,
|
||||
Fee: '100',
|
||||
TransactionType: 'AccountSet',
|
||||
Flags: 0,
|
||||
LastLedgerSequence: 1
|
||||
});
|
||||
|
||||
const multiSigningJson = transaction.getMultiSigningJson();
|
||||
const t1 = Transaction.from_json(multiSigningJson);
|
||||
|
||||
const a1 = 'rPMh7Pi9ct699iZUTWaytJUoHcJ7cgyziK';
|
||||
const a2 = 'rH4KEcG9dEwGwpn6AyoWK9cZPLL4RLSmWW';
|
||||
|
||||
const s1 = t1.multiSign(a1, 'alice');
|
||||
assert.deepEqual(s1, {
|
||||
Account: 'rPMh7Pi9ct699iZUTWaytJUoHcJ7cgyziK',
|
||||
TxnSignature: '3045022100DB13DC794DDFA1E27D099CDBFC7DB5B1EE892AD1725B0CEEE97D8B1C4C2055C7022030B3372C96D08106594B3CF8CDF88E05CC6260C51954F02387289CB69B839D7A',
|
||||
SigningPubKey: '0388935426E0D08083314842EDFBB2D517BD47699F9A4527318A8E10468C97C052'
|
||||
|
||||
});
|
||||
|
||||
const s2 = t1.multiSign(a2, 'bob');
|
||||
assert.deepEqual(s2, {
|
||||
Account: 'rH4KEcG9dEwGwpn6AyoWK9cZPLL4RLSmWW',
|
||||
TxnSignature: '304402207A22109088069C5ABE3E961C2F85B2B8111C5666C869E8BA3F2A57C2ECEA7FC402205F9D87FB42266CC498FCE9B4904955D0E6D5F44D092596F5DE3E25843F6D10AB',
|
||||
SigningPubKey: '02691AC5AE1C4C333AE5DF8A93BDC495F0EEBFC6DB0DA7EB6EF808F3AFC006E3FE'
|
||||
|
||||
});
|
||||
|
||||
transaction.addMultiSigner(s1);
|
||||
transaction.addMultiSigner(s2);
|
||||
|
||||
assert.deepEqual(transaction.getMultiSigners(), [
|
||||
{Signer: s2},
|
||||
{Signer: s1}
|
||||
]);
|
||||
});
|
||||
|
||||
it('Multisign -- missing LastLedgerSequence', function() {
|
||||
const transaction = Transaction.from_json({
|
||||
Account: 'rG1QQv2nh2gr7RCZ1P8YYcBUKCCN633jCn',
|
||||
Sequence: 1,
|
||||
Fee: '100',
|
||||
TransactionType: 'AccountSet',
|
||||
Flags: 0
|
||||
});
|
||||
|
||||
assert.throws(function() {
|
||||
transaction.getMultiSigningJson();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user