Skip to content

Commit

Permalink
Merge pull request #307 from Concordium/remove-shielded-transfers
Browse files Browse the repository at this point in the history
Remove shielded transfers
  • Loading branch information
DOBEN authored May 27, 2024
2 parents be58014 + 8d8fb38 commit d558534
Show file tree
Hide file tree
Showing 3 changed files with 6 additions and 212 deletions.
8 changes: 5 additions & 3 deletions ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@

## Unreleased

- Rename subcommand `TransactionSubmit` to `TransactionSignAndSubmit`.
- Add subcommand `TransactionSubmit` to submit a signed transaction on chain.
- Add subcommand `TransactionAddSignature` to add a signature to a partially-signed transaction.
- Remove command `transaction send-shielded` to disable the transfer of CCD from the shielded balance of the account to the shielded balance of another account.
- Remove command `account shield` to disable the transfer of CCD from the public balance to the shielded balance of an account.
- Rename command `transaction submit` to `transaction sign-and-submit`.
- Add command `transaction submit` to submit a signed transaction on chain.
- Add command `transaction add-signature` to add a signature to a partially-signed transaction.
- Add optional `--out` flag to all transaction-creating commands to output a partially-singed transaction to a file.
- Update GHC version to 9.6.4 (lts-22.9).
- Update Rust version to 1.73.
Expand Down
47 changes: 0 additions & 47 deletions src/Concordium/Client/Commands.hs
Original file line number Diff line number Diff line change
Expand Up @@ -216,17 +216,6 @@ data TransactionCmd
{ tdcFile :: !FilePath,
tdcInteractionOpts :: !InteractionOpts
}
| TransactionEncryptedTransfer
{ tetTransactionOpts :: !(TransactionOpts (Maybe Energy)),
-- | Address of the receiver.
tetReceiver :: !Text,
-- | Amount to send.
tetAmount :: !Amount,
-- | Which indices to use as inputs to the encrypted amount transfer.
-- If none are provided all existing ones will be used.
tetIndex :: !(Maybe Int),
tetMemo :: !(Maybe MemoInput)
}
| -- | Register data on chain.
TransactionRegisterData
{ -- | File containing the data.
Expand All @@ -250,13 +239,6 @@ data AccountCmd
aukCredId :: !CredentialRegistrationID,
aukTransactionOpts :: !(TransactionOpts (Maybe Energy))
}
| -- | Transfer part of the public balance to the encrypted balance of the
-- account.
AccountEncrypt
{ aeTransactionOpts :: !(TransactionOpts (Maybe Energy)),
-- | Amount to transfer from public to encrypted balance.
aeAmount :: !Amount
}
| -- | Transfer part of the encrypted balance to the public balance of the
-- account.
AccountDecrypt
Expand Down Expand Up @@ -720,7 +702,6 @@ transactionCmds =
<> transactionSendCcdCmd
<> transactionWithScheduleCmd
<> transactionDeployCredentialCmd
<> transactionEncryptedTransferCmd
<> transactionRegisterDataCmd
)
)
Expand Down Expand Up @@ -920,21 +901,6 @@ transactionWithScheduleCmd =
Nothing -> Left "Starting point could not be read."
Just time -> return (utcTimeToTimestamp time)

transactionEncryptedTransferCmd :: Mod CommandFields TransactionCmd
transactionEncryptedTransferCmd = command "send-shielded" sendEncryptedInfo
where
sendEncryptedInfo :: ParserInfo TransactionCmd
sendEncryptedInfo =
info
( TransactionEncryptedTransfer
<$> transactionOptsParser
<*> strOption (long "receiver" <> metavar "RECEIVER-ACCOUNT" <> help "Address of the receiver.")
<*> option (eitherReader amountFromStringInform) (long "amount" <> metavar "CCD-AMOUNT" <> help "Amount of CCDs to send.")
<*> optional (option auto (long "index" <> metavar "INDEX" <> help "Optionally specify the index up to which incoming shielded amounts should be used."))
<*> memoInputParser
)
(progDesc "Transfer CCD from the shielded balance of the account to the shielded balance of another account.")

transactionRegisterDataCmd :: Mod CommandFields TransactionCmd
transactionRegisterDataCmd =
command
Expand All @@ -958,7 +924,6 @@ accountCmds =
<> accountListCmd
<> accountUpdateKeysCmd
<> accountUpdateCredentialsCmd
<> accountEncryptCmd
<> accountDecryptCmd
<> accountShowAliasCmd
)
Expand Down Expand Up @@ -991,18 +956,6 @@ accountListCmd =
(progDesc "List all accounts.")
)

accountEncryptCmd :: Mod CommandFields AccountCmd
accountEncryptCmd =
command
"shield"
( info
( AccountEncrypt
<$> transactionOptsParser
<*> option (eitherReader amountFromStringInform) (long "amount" <> metavar "CCD-AMOUNT" <> help "The amount to transfer to shielded balance.")
)
(progDesc "Transfer an amount from public to shielded balance of the account.")
)

accountDecryptCmd :: Mod CommandFields AccountCmd
accountDecryptCmd =
command
Expand Down
163 changes: 1 addition & 162 deletions src/Concordium/Client/Runner.hs
Original file line number Diff line number Diff line change
Expand Up @@ -883,52 +883,6 @@ processTransactionCmd action baseCfgDir verbose backend =
let outFile = toOutFile txOpts
liftIO $ transferWithScheduleTransactionConfirm ttxCfg (ioConfirm intOpts)
signAndProcessTransaction_ verbose txCfg pl intOpts outFile backend
TransactionEncryptedTransfer txOpts receiver amount index maybeMemo -> do
baseCfg <- getBaseConfig baseCfgDir verbose
when verbose $ do
runPrinter $ printBaseConfig baseCfg
putStrLn ""

accCfg <- getAccountCfgFromTxOpts baseCfg txOpts
let senderAddr = esdAddress accCfg

encryptedSecretKey <-
case esdEncryptionKey accCfg of
Nothing ->
logFatal ["Missing account encryption secret key for account: " ++ show senderAddr]
Just x -> return x
secretKey <- decryptAccountEncryptionSecretKeyInteractive encryptedSecretKey `withLogFatalIO` ("Couldn't decrypt account encryption secret key: " ++)

receiverAcc <- getAccountAddressArg (bcAccountNameMap baseCfg) receiver

withClient backend $ do
transferData <- getEncryptedAmountTransferData (naAddr senderAddr) receiverAcc amount index secretKey
cs <- getResponseValueOrDie =<< getConsensusInfo
payload <- liftIO $ do
res <- case maybeMemo of
Nothing -> return $ Types.EncryptedAmountTransfer (naAddr receiverAcc) transferData
Just memoInput -> do
memo <- checkAndGetMemo memoInput $ Queries.csProtocolVersion cs
return $ Types.EncryptedAmountTransferWithMemo (naAddr receiverAcc) memo transferData
return $ Types.encodePayload res
let nrgCost _ = return $ Just $ encryptedTransferEnergyCost $ Types.payloadSize payload
txCfg <- liftIO (getTransactionCfg baseCfg txOpts nrgCost)

let ettCfg =
EncryptedTransferTransactionConfig
{ ettTransferData = transferData,
ettTransactionCfg = txCfg,
ettReceiver = receiverAcc,
ettAmount = amount
}
liftIO $ when verbose $ do
runPrinter $ printSelectedKeyConfig $ tcEncryptedSigningData txCfg
putStrLn ""

let intOpts = toInteractionOpts txOpts
let outFile = toOutFile txOpts
encryptedTransferTransactionConfirm ettCfg (ioConfirm intOpts)
signAndProcessTransaction_ verbose txCfg payload intOpts outFile backend
TransactionRegisterData file txOpts -> do
baseCfg <- getBaseConfig baseCfgDir verbose
rdCfg <- getRegisterDataTransactionCfg baseCfg txOpts file
Expand Down Expand Up @@ -1191,52 +1145,6 @@ data TransferWithScheduleTransactionConfig = TransferWithScheduleTransactionConf
twstcSchedule :: [(Time.Timestamp, Types.Amount)]
}

data EncryptedTransferTransactionConfig = EncryptedTransferTransactionConfig
{ ettTransactionCfg :: TransactionConfig,
ettReceiver :: NamedAddress,
ettAmount :: Types.Amount,
ettTransferData :: !Enc.EncryptedAmountTransferData
}

getEncryptedAmountTransferData :: ID.AccountAddress -> NamedAddress -> Types.Amount -> Maybe Int -> ElgamalSecretKey -> ClientMonad IO Enc.EncryptedAmountTransferData
getEncryptedAmountTransferData senderAddr ettReceiver ettAmount idx secretKey = do
-- get encrypted amounts for the sender
bbHash <- extractResponseValueOrDie Queries.biBlockHash =<< getBlockInfo Best
Types.AccountInfo{aiAccountEncryptedAmount = a@Types.AccountEncryptedAmount{..}} <-
getResponseValueOrDie =<< getAccountInfo (Types.AccAddress senderAddr) (Given bbHash)
let listOfEncryptedAmounts = Types.getIncomingAmountsList a
taker <- case idx of
Nothing -> return id
Just v ->
if v < fromIntegral _startIndex
|| v > fromIntegral _startIndex + length listOfEncryptedAmounts
then logFatal ["The index provided must be at least the index of the first incoming amount on the account and at most `start index + number of incoming amounts`"]
else return $ take (v - fromIntegral _startIndex)
-- get receiver's public encryption key
air <- getResponseValueOrDie =<< getAccountInfo (Types.AccAddress $ naAddr ettReceiver) (Given bbHash)
globalContext <- getResponseValueOrDie =<< getCryptographicParameters (Given bbHash)
let receiverPk = ID._elgamalPublicKey $ Types.aiAccountEncryptionKey air
-- precomputed table for speeding up decryption
let table = Enc.computeTable globalContext (2 ^ (16 :: Int))
decoder = Enc.decryptAmount table secretKey
selfDecrypted = decoder _selfAmount
-- aggregation of idx encrypted amounts
inputEncAmounts = taker listOfEncryptedAmounts
aggAmounts = foldl' (<>) _selfAmount inputEncAmounts
totalEncryptedAmount = foldl' (+) selfDecrypted $ fmap decoder inputEncAmounts
unless (totalEncryptedAmount >= ettAmount) $
logFatal [printf "The requested transfer (%s) is more than the total encrypted balance (%s)." (Types.amountToString ettAmount) (Types.amountToString totalEncryptedAmount)]
-- index indicating which encrypted amounts we used as input
let aggIndex = case idx of
Nothing -> Enc.EncryptedAmountAggIndex (Enc.theAggIndex _startIndex + fromIntegral (length listOfEncryptedAmounts))
Just idx' -> Enc.EncryptedAmountAggIndex (fromIntegral idx')
-- we use the supplied index if given. We already checked above that it is within bounds.
aggAmount = Enc.makeAggregatedDecryptedAmount aggAmounts totalEncryptedAmount aggIndex
liftIO $
Enc.makeEncryptedAmountTransferData globalContext receiverPk secretKey aggAmount ettAmount >>= \case
Nothing -> logFatal ["Could not create transfer. Likely the provided secret key is incorrect."]
Just ettTransferData -> return ettTransferData

-- | Returns the UTCTime date when the baker cooldown on reducing stake/removing a baker will end, using on chain parameters
getBakerCooldown :: Queries.EChainParametersAndKeys -> ClientMonad IO UTCTime
getBakerCooldown (Queries.EChainParametersAndKeys (ecpParams :: ChainParameters' cpv) _) = do
Expand Down Expand Up @@ -1318,27 +1226,12 @@ data AccountUpdateCredentialsTransactionCfg = AccountUpdateCredentialsTransactio
auctcNewThreshold :: ID.AccountThreshold
}

-- | Resolved configuration for transferring from public to encrypted balance.
data AccountEncryptTransactionConfig = AccountEncryptTransactionConfig
{ aeTransactionCfg :: TransactionConfig,
aeAmount :: Types.Amount
}

-- | Resolved configuration for transferring from encrypted to public balance.
data AccountDecryptTransactionConfig = AccountDecryptTransactionConfig
{ adTransactionCfg :: TransactionConfig,
adTransferData :: Enc.SecToPubAmountTransferData
}

-- | Resolve configuration for transferring an amount from public to encrypted
-- balance of an account.
getAccountEncryptTransactionCfg :: BaseConfig -> TransactionOpts (Maybe Types.Energy) -> Types.Amount -> Types.PayloadSize -> IO AccountEncryptTransactionConfig
getAccountEncryptTransactionCfg baseCfg txOpts aeAmount payloadSize = do
aeTransactionCfg <- getTransactionCfg baseCfg txOpts nrgCost
return AccountEncryptTransactionConfig{..}
where
nrgCost _ = return $ Just $ accountEncryptEnergyCost payloadSize

-- | Resolve configuration for transferring an amount from encrypted to public
-- balance of an account.
getAccountDecryptTransferData :: ID.AccountAddress -> Types.Amount -> ElgamalSecretKey -> Maybe Int -> ClientMonad IO Enc.SecToPubAmountTransferData
Expand Down Expand Up @@ -1446,25 +1339,6 @@ transferWithScheduleTransactionConfirm ttxCfg confirm = do
confirmed <- askConfirmation Nothing
unless confirmed exitTransactionCancelled

encryptedTransferTransactionConfirm :: (MonadIO m) => EncryptedTransferTransactionConfig -> Bool -> m ()
encryptedTransferTransactionConfirm EncryptedTransferTransactionConfig{..} confirm = do
let TransactionConfig
{ tcEnergy = energy,
tcExpiry = expiry,
tcEncryptedSigningData = EncryptedSigningData{esdAddress = addr}
} =
ettTransactionCfg

logInfo
[ printf "transferring %s CCD from shielded balance of account %s to %s" (Types.amountToString ettAmount) (showNamedAddress addr) (showNamedAddress ettReceiver),
printf "allowing up to %s to be spent as transaction fee" (showNrg energy),
printf "transaction expires on %s" (showTimeFormatted $ timeFromTransactionExpiryTime expiry)
]

when confirm $ do
confirmed <- askConfirmation Nothing
unless confirmed exitTransactionCancelled

-- | Query the chain for the minimum baker stake threshold.
-- Die printing an error message containing the nature of the error if such occured.
getBakerStakeThresholdOrDie :: ClientMonad IO Types.Amount
Expand Down Expand Up @@ -1552,25 +1426,6 @@ accountUpdateCredentialsTransactionConfirm AccountUpdateCredentialsTransactionCf
confirmed <- askConfirmation Nothing
unless confirmed exitTransactionCancelled

accountEncryptTransactionConfirm :: AccountEncryptTransactionConfig -> Bool -> IO ()
accountEncryptTransactionConfirm AccountEncryptTransactionConfig{..} confirm = do
let TransactionConfig
{ tcEnergy = energy,
tcExpiry = expiry,
tcEncryptedSigningData = EncryptedSigningData{esdAddress = addr}
} =
aeTransactionCfg

logInfo $
[ printf "transferring %s CCD from public to shielded balance of account %s" (Types.amountToString aeAmount) (showNamedAddress addr),
printf "allowing up to %s to be spent as transaction fee" (showNrg energy),
printf "transaction expires on %s" (showTimeFormatted $ timeFromTransactionExpiryTime expiry)
]

when confirm $ do
confirmed <- askConfirmation Nothing
unless confirmed exitTransactionCancelled

accountDecryptTransactionConfirm :: (MonadIO m) => AccountDecryptTransactionConfig -> Bool -> m ()
accountDecryptTransactionConfirm AccountDecryptTransactionConfig{..} confirm = do
let TransactionConfig
Expand Down Expand Up @@ -1970,23 +1825,6 @@ processAccountCmd action baseCfgDir verbose backend =
}
liftIO $ accountUpdateCredentialsTransactionConfirm aucCfg (ioConfirm intOpts)
signAndProcessTransaction_ verbose txCfg epayload intOpts (toOutFile txOpts) backend
AccountEncrypt{..} -> do
baseCfg <- getBaseConfig baseCfgDir verbose
when verbose $ do
runPrinter $ printBaseConfig baseCfg
putStrLn ""

let pl = Types.encodePayload $ Types.TransferToEncrypted aeAmount

aetxCfg <- getAccountEncryptTransactionCfg baseCfg aeTransactionOpts aeAmount (Types.payloadSize pl)
let txCfg = aeTransactionCfg aetxCfg
when verbose $ do
runPrinter $ printSelectedKeyConfig $ tcEncryptedSigningData txCfg
putStrLn ""

let intOpts = toInteractionOpts aeTransactionOpts
accountEncryptTransactionConfirm aetxCfg (ioConfirm intOpts)
withClient backend $ signAndProcessTransaction_ verbose txCfg pl intOpts (toOutFile aeTransactionOpts) backend
AccountDecrypt{..} -> do
baseCfg <- getBaseConfig baseCfgDir verbose
when verbose $ do
Expand Down Expand Up @@ -4649,6 +4487,7 @@ convertTransactionJsonPayload = \case
return $ Types.Transfer transferTo transferAmount
CT.RemoveBaker -> return $ Types.RemoveBaker
CT.TransferToPublic{..} -> return $ Types.TransferToPublic{..}
-- Note: The following two types are not supported anymore in protocol version 7 or above.
-- FIXME: The following two should have the inputs changed so that they are usable.
-- They should only specify the amount and the index, and possibly the input encrypted amounts,
-- but the proofs should be automatically generated here.
Expand Down

0 comments on commit d558534

Please sign in to comment.