Allow the same account to be passed multiple times to a single instruction (#7795)

This commit is contained in:
Jack May
2020-01-22 09:11:56 -08:00
committed by GitHub
parent d854e90c23
commit 023074650f
33 changed files with 1392 additions and 765 deletions

View File

@ -164,15 +164,16 @@ impl ExchangeProcessor {
error!("Not enough accounts");
return Err(InstructionError::InvalidArgument);
}
Self::is_account_unallocated(&keyed_accounts[NEW_ACCOUNT_INDEX].account.data)?;
Self::is_account_unallocated(&keyed_accounts[NEW_ACCOUNT_INDEX].try_account_ref()?.data)?;
Self::serialize(
&ExchangeState::Account(
TokenAccountInfo::default()
.owner(&keyed_accounts[OWNER_INDEX].unsigned_key())
.tokens(100_000, 100_000, 100_000, 100_000),
),
&mut keyed_accounts[NEW_ACCOUNT_INDEX].account.data,
&mut keyed_accounts[NEW_ACCOUNT_INDEX]
.try_account_ref_mut()?
.data,
)
}
@ -191,13 +192,13 @@ impl ExchangeProcessor {
}
let mut to_account =
Self::deserialize_account(&keyed_accounts[TO_ACCOUNT_INDEX].account.data)?;
Self::deserialize_account(&keyed_accounts[TO_ACCOUNT_INDEX].try_account_ref()?.data)?;
if &faucet::id() == keyed_accounts[FROM_ACCOUNT_INDEX].unsigned_key() {
to_account.tokens[token] += tokens;
} else {
let state: ExchangeState =
bincode::deserialize(&keyed_accounts[FROM_ACCOUNT_INDEX].account.data)
bincode::deserialize(&keyed_accounts[FROM_ACCOUNT_INDEX].try_account_ref()?.data)
.map_err(Self::map_to_invalid_arg)?;
match state {
ExchangeState::Account(mut from_account) => {
@ -216,7 +217,9 @@ impl ExchangeProcessor {
Self::serialize(
&ExchangeState::Account(from_account),
&mut keyed_accounts[FROM_ACCOUNT_INDEX].account.data,
&mut keyed_accounts[FROM_ACCOUNT_INDEX]
.try_account_ref_mut()?
.data,
)?;
}
ExchangeState::Trade(mut from_trade) => {
@ -244,7 +247,9 @@ impl ExchangeProcessor {
Self::serialize(
&ExchangeState::Trade(from_trade),
&mut keyed_accounts[FROM_ACCOUNT_INDEX].account.data,
&mut keyed_accounts[FROM_ACCOUNT_INDEX]
.try_account_ref_mut()?
.data,
)?;
}
_ => {
@ -256,7 +261,7 @@ impl ExchangeProcessor {
Self::serialize(
&ExchangeState::Account(to_account),
&mut keyed_accounts[TO_ACCOUNT_INDEX].account.data,
&mut keyed_accounts[TO_ACCOUNT_INDEX].try_account_ref_mut()?.data,
)
}
@ -273,9 +278,10 @@ impl ExchangeProcessor {
return Err(InstructionError::InvalidArgument);
}
Self::is_account_unallocated(&keyed_accounts[ORDER_INDEX].account.data)?;
Self::is_account_unallocated(&keyed_accounts[ORDER_INDEX].try_account_ref()?.data)?;
let mut account = Self::deserialize_account(&keyed_accounts[ACCOUNT_INDEX].account.data)?;
let mut account =
Self::deserialize_account(&keyed_accounts[ACCOUNT_INDEX].try_account_ref_mut()?.data)?;
if &account.owner != keyed_accounts[OWNER_INDEX].unsigned_key() {
error!("Signer does not own account");
@ -308,11 +314,11 @@ impl ExchangeProcessor {
price: info.price,
tokens_settled: 0,
}),
&mut keyed_accounts[ORDER_INDEX].account.data,
&mut keyed_accounts[ORDER_INDEX].try_account_ref_mut()?.data,
)?;
Self::serialize(
&ExchangeState::Account(account),
&mut keyed_accounts[ACCOUNT_INDEX].account.data,
&mut keyed_accounts[ACCOUNT_INDEX].try_account_ref_mut()?.data,
)
}
@ -325,7 +331,7 @@ impl ExchangeProcessor {
return Err(InstructionError::InvalidArgument);
}
let order = Self::deserialize_order(&keyed_accounts[ORDER_INDEX].account.data)?;
let order = Self::deserialize_order(&keyed_accounts[ORDER_INDEX].try_account_ref()?.data)?;
if &order.owner != keyed_accounts[OWNER_INDEX].unsigned_key() {
error!("Signer does not own trade");
@ -344,7 +350,7 @@ impl ExchangeProcessor {
// Turn trade order into a token account
Self::serialize(
&ExchangeState::Account(account),
&mut keyed_accounts[ORDER_INDEX].account.data,
&mut keyed_accounts[ORDER_INDEX].try_account_ref_mut()?.data,
)
}
@ -358,11 +364,13 @@ impl ExchangeProcessor {
return Err(InstructionError::InvalidArgument);
}
let mut to_order = Self::deserialize_order(&keyed_accounts[TO_ORDER_INDEX].account.data)?;
let mut to_order =
Self::deserialize_order(&keyed_accounts[TO_ORDER_INDEX].try_account_ref()?.data)?;
let mut from_order =
Self::deserialize_order(&keyed_accounts[FROM_ORDER_INDEX].account.data)?;
let mut profit_account =
Self::deserialize_account(&keyed_accounts[PROFIT_ACCOUNT_INDEX].account.data)?;
Self::deserialize_order(&keyed_accounts[FROM_ORDER_INDEX].try_account_ref()?.data)?;
let mut profit_account = Self::deserialize_account(
&keyed_accounts[PROFIT_ACCOUNT_INDEX].try_account_ref()?.data,
)?;
if to_order.side != OrderSide::Ask {
error!("To trade is not a To");
@ -397,12 +405,12 @@ impl ExchangeProcessor {
// Turn into token account
Self::serialize(
&ExchangeState::Account(Self::trade_to_token_account(&from_order)),
&mut keyed_accounts[TO_ORDER_INDEX].account.data,
&mut keyed_accounts[TO_ORDER_INDEX].try_account_ref_mut()?.data,
)?;
} else {
Self::serialize(
&ExchangeState::Trade(to_order),
&mut keyed_accounts[TO_ORDER_INDEX].account.data,
&mut keyed_accounts[TO_ORDER_INDEX].try_account_ref_mut()?.data,
)?;
}
@ -410,18 +418,20 @@ impl ExchangeProcessor {
// Turn into token account
Self::serialize(
&ExchangeState::Account(Self::trade_to_token_account(&from_order)),
&mut keyed_accounts[FROM_ORDER_INDEX].account.data,
&mut keyed_accounts[FROM_ORDER_INDEX].try_account_ref_mut()?.data,
)?;
} else {
Self::serialize(
&ExchangeState::Trade(from_order),
&mut keyed_accounts[FROM_ORDER_INDEX].account.data,
&mut keyed_accounts[FROM_ORDER_INDEX].try_account_ref_mut()?.data,
)?;
}
Self::serialize(
&ExchangeState::Account(profit_account),
&mut keyed_accounts[PROFIT_ACCOUNT_INDEX].account.data,
&mut keyed_accounts[PROFIT_ACCOUNT_INDEX]
.try_account_ref_mut()?
.data,
)
}
}