stellar_base/operations/
bump_sequence.rs

1use crate::crypto::MuxedAccount;
2use crate::error::{Error, Result};
3use crate::operations::Operation;
4use crate::xdr;
5
6#[derive(Debug, Clone, PartialEq, Eq)]
7pub struct BumpSequenceOperation {
8    source_account: Option<MuxedAccount>,
9    bump_to: i64,
10}
11
12#[derive(Debug, Default)]
13pub struct BumpSequenceOperationBuilder {
14    source_account: Option<MuxedAccount>,
15    bump_to: Option<i64>,
16}
17
18impl BumpSequenceOperation {
19    /// Retrieves the operation source account.
20    pub fn source_account(&self) -> &Option<MuxedAccount> {
21        &self.source_account
22    }
23
24    /// Retrieves a reference to the operation source account.
25    pub fn source_account_mut(&mut self) -> &mut Option<MuxedAccount> {
26        &mut self.source_account
27    }
28
29    /// Retrieves the operatino bump to.
30    pub fn bump_to(&self) -> &i64 {
31        &self.bump_to
32    }
33
34    /// Retrieves the operatino bump to.
35    pub fn bump_to_mut(&mut self) -> &mut i64 {
36        &mut self.bump_to
37    }
38
39    /// Returns the xdr operation body.
40    pub fn to_xdr_operation_body(&self) -> Result<xdr::OperationBody> {
41        let bump_to = xdr::SequenceNumber(self.bump_to);
42        let inner = xdr::BumpSequenceOp { bump_to };
43        Ok(xdr::OperationBody::BumpSequence(inner))
44    }
45
46    /// Creates from the xdr operation body.
47    pub fn from_xdr_operation_body(
48        source_account: Option<MuxedAccount>,
49        x: &xdr::BumpSequenceOp,
50    ) -> Result<BumpSequenceOperation> {
51        let bump_to = x.bump_to.0;
52        Ok(BumpSequenceOperation {
53            source_account,
54            bump_to,
55        })
56    }
57}
58
59impl BumpSequenceOperationBuilder {
60    pub fn new() -> BumpSequenceOperationBuilder {
61        Default::default()
62    }
63
64    pub fn with_source_account<S>(mut self, source: S) -> BumpSequenceOperationBuilder
65    where
66        S: Into<MuxedAccount>,
67    {
68        self.source_account = Some(source.into());
69        self
70    }
71
72    pub fn with_bump_to(mut self, bump_to: i64) -> BumpSequenceOperationBuilder {
73        self.bump_to = Some(bump_to);
74        self
75    }
76
77    pub fn build(self) -> Result<Operation> {
78        let bump_to = self
79            .bump_to
80            .ok_or_else(|| Error::InvalidOperation("missing bump sequence bump to".to_string()))?;
81
82        if bump_to < 0 {
83            return Err(Error::InvalidOperation(
84                "bump sequence bump to must be non negative".to_string(),
85            ));
86        }
87
88        Ok(Operation::BumpSequence(BumpSequenceOperation {
89            source_account: self.source_account,
90            bump_to,
91        }))
92    }
93}
94
95#[cfg(test)]
96mod tests {
97
98    use crate::network::Network;
99    use crate::operations::tests::*;
100    use crate::operations::Operation;
101    use crate::transaction::{Transaction, TransactionEnvelope, MIN_BASE_FEE};
102    use crate::xdr::{XDRDeserialize, XDRSerialize};
103
104    #[test]
105    fn test_bump_sequence() {
106        let kp = keypair0();
107        let op = Operation::new_bump_sequence()
108            .with_bump_to(123)
109            .build()
110            .unwrap();
111
112        let mut tx = Transaction::builder(kp.public_key(), 3556091187167235, MIN_BASE_FEE)
113            .add_operation(op)
114            .into_transaction()
115            .unwrap();
116        tx.sign(kp.as_ref(), &Network::new_test()).unwrap();
117        let envelope = tx.to_envelope();
118        let xdr = envelope.xdr_base64().unwrap();
119        let expected = "AAAAAgAAAADg3G3hclysZlFitS+s5zWyiiJD5B0STWy5LXCj6i5yxQAAAGQADKI/AAAAAwAAAAAAAAAAAAAAAQAAAAAAAAALAAAAAAAAAHsAAAAAAAAAAeoucsUAAABAFjXV5orPOkYP+zKGyNKWNJPkZ1UG2n7zyj33W5LHlx1LkD+8vLtB8/GyamKUs7qThchbHdRS9lSBUnvqNkNeCg==";
120        assert_eq!(expected, xdr);
121        let back = TransactionEnvelope::from_xdr_base64(&xdr).unwrap();
122        assert_eq!(envelope, back);
123    }
124
125    #[test]
126    fn test_bump_sequence_with_source() {
127        let kp = keypair0();
128        let kp1 = keypair1();
129        let op = Operation::new_bump_sequence()
130            .with_source_account(kp1.public_key())
131            .with_bump_to(i64::MAX)
132            .build()
133            .unwrap();
134
135        let mut tx = Transaction::builder(kp.public_key(), 3556091187167235, MIN_BASE_FEE)
136            .add_operation(op)
137            .into_transaction()
138            .unwrap();
139        tx.sign(kp.as_ref(), &Network::new_test()).unwrap();
140        let envelope = tx.to_envelope();
141        let xdr = envelope.xdr_base64().unwrap();
142        let expected = "AAAAAgAAAADg3G3hclysZlFitS+s5zWyiiJD5B0STWy5LXCj6i5yxQAAAGQADKI/AAAAAwAAAAAAAAAAAAAAAQAAAAEAAAAAJcrx2g/Hbs/ohF5CVFG7B5JJSJR+OqDKzDGK7dKHZH4AAAALf/////////8AAAAAAAAAAeoucsUAAABAvmRGh/Fe460s9zn2gNu6onhD76G7AL7M3KQ9Ps67y92kQUz0Aw8leVvjAkAvuapExekSc1iMRAkS0uszaQIRCA==";
143        assert_eq!(expected, xdr);
144        let back = TransactionEnvelope::from_xdr_base64(&xdr).unwrap();
145        assert_eq!(envelope, back);
146    }
147}