Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
P
plugin
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
JIRA
JIRA
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
link33
plugin
Commits
c989cfb0
Commit
c989cfb0
authored
Dec 07, 2018
by
heyubin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add by hyb for multisig cmd
parent
1cecae74
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
69 additions
and
51 deletions
+69
-51
multisig.go
plugin/dapp/multisig/commands/multisig.go
+59
-26
multisig.go
plugin/dapp/multisig/executor/multisig.go
+10
-25
No files found.
plugin/dapp/multisig/commands/multisig.go
View file @
c989cfb0
...
@@ -25,29 +25,62 @@ func MultiSigCmd() *cobra.Command {
...
@@ -25,29 +25,62 @@ func MultiSigCmd() *cobra.Command {
Short
:
"multisig management"
,
Short
:
"multisig management"
,
Args
:
cobra
.
MinimumNArgs
(
1
),
Args
:
cobra
.
MinimumNArgs
(
1
),
}
}
cmd
.
AddCommand
(
MultiSigAccountCmd
(),
MultiSigOwnerCmd
(),
MultiSigTxCmd
(),
)
return
cmd
}
func
MultiSigAccountCmd
()
*
cobra
.
Command
{
cmd
:=
&
cobra
.
Command
{
Use
:
"account"
,
Short
:
"multisig account"
,
Args
:
cobra
.
MinimumNArgs
(
1
),
}
cmd
.
AddCommand
(
cmd
.
AddCommand
(
CreateMultiSigAccCreateCmd
(),
CreateMultiSigAccCreateCmd
(),
CreateMultiSigAccWeightModifyCmd
(),
CreateMultiSigAccDailyLimitModifyCmd
(),
GetMultiSigAccCountCmd
(),
GetMultiSigAccountsCmd
(),
GetMultiSigAccountInfoCmd
(),
GetMultiSigAccUnSpentTodayCmd
(),
GetMultiSigAccAssetsCmd
(),
GetMultiSigAccAllAddressCmd
(),
)
return
cmd
}
func
MultiSigOwnerCmd
()
*
cobra
.
Command
{
cmd
:=
&
cobra
.
Command
{
Use
:
"owner"
,
Short
:
"multisig owner"
,
Args
:
cobra
.
MinimumNArgs
(
1
),
}
cmd
.
AddCommand
(
CreateMultiSigAccOwnerAddCmd
(),
CreateMultiSigAccOwnerAddCmd
(),
CreateMultiSigAccOwnerDelCmd
(),
CreateMultiSigAccOwnerDelCmd
(),
CreateMultiSigAccOwnerModifyCmd
(),
CreateMultiSigAccOwnerModifyCmd
(),
CreateMultiSigAccOwnerReplaceCmd
(),
CreateMultiSigAccOwnerReplaceCmd
(),
CreateMultiSigAccWeightModifyCmd
(),
)
CreateMultiSigAccDailyLimitModifyCmd
(),
return
cmd
}
func
MultiSigTxCmd
()
*
cobra
.
Command
{
cmd
:=
&
cobra
.
Command
{
Use
:
"tx"
,
Short
:
"multisig tx"
,
Args
:
cobra
.
MinimumNArgs
(
1
),
}
cmd
.
AddCommand
(
CreateMultiSigConfirmTxCmd
(),
CreateMultiSigConfirmTxCmd
(),
CreateMultiSigAccTransferInCmd
(),
CreateMultiSigAccTransferInCmd
(),
CreateMultiSigAccTransferOutCmd
(),
CreateMultiSigAccTransferOutCmd
(),
GetMultiSigAccCountCmd
(),
GetMultiSigAccountsCmd
(),
GetMultiSigAccountInfoCmd
(),
GetMultiSigAccTxCountCmd
(),
GetMultiSigAccTxCountCmd
(),
GetMultiSigTxidsCmd
(),
GetMultiSigTxidsCmd
(),
GetMultiSigTxInfoCmd
(),
GetMultiSigTxInfoCmd
(),
GetMultiSigTxConfirmedWeightCmd
(),
GetMultiSigTxConfirmedWeightCmd
(),
GetMultiSigAccUnSpentTodayCmd
(),
GetMultiSigAccAssetsCmd
(),
GetMultiSigAccAllAddressCmd
(),
)
)
return
cmd
return
cmd
}
}
...
@@ -159,7 +192,7 @@ func createMultiSigAccTransfer(cmd *cobra.Command, args []string) {
...
@@ -159,7 +192,7 @@ func createMultiSigAccTransfer(cmd *cobra.Command, args []string) {
// CreateMultiSigAccOwnerAddCmd create raw MultiSigAccOwnerAdd transaction
// CreateMultiSigAccOwnerAddCmd create raw MultiSigAccOwnerAdd transaction
func
CreateMultiSigAccOwnerAddCmd
()
*
cobra
.
Command
{
func
CreateMultiSigAccOwnerAddCmd
()
*
cobra
.
Command
{
cmd
:=
&
cobra
.
Command
{
cmd
:=
&
cobra
.
Command
{
Use
:
"
owner_
add"
,
Use
:
"add"
,
Short
:
"Create a add owner transaction"
,
Short
:
"Create a add owner transaction"
,
Run
:
createOwnerAddTransfer
,
Run
:
createOwnerAddTransfer
,
}
}
...
@@ -200,7 +233,7 @@ func createOwnerAddTransfer(cmd *cobra.Command, args []string) {
...
@@ -200,7 +233,7 @@ func createOwnerAddTransfer(cmd *cobra.Command, args []string) {
// CreateMultiSigAccOwnerDelCmd create raw MultiSigAccOwnerDel transaction
// CreateMultiSigAccOwnerDelCmd create raw MultiSigAccOwnerDel transaction
func
CreateMultiSigAccOwnerDelCmd
()
*
cobra
.
Command
{
func
CreateMultiSigAccOwnerDelCmd
()
*
cobra
.
Command
{
cmd
:=
&
cobra
.
Command
{
cmd
:=
&
cobra
.
Command
{
Use
:
"
owner_
del"
,
Use
:
"del"
,
Short
:
"Create a del owner transaction"
,
Short
:
"Create a del owner transaction"
,
Run
:
createOwnerDelTransfer
,
Run
:
createOwnerDelTransfer
,
}
}
...
@@ -235,7 +268,7 @@ func createOwnerDelTransfer(cmd *cobra.Command, args []string) {
...
@@ -235,7 +268,7 @@ func createOwnerDelTransfer(cmd *cobra.Command, args []string) {
// CreateMultiSigAccOwnerModifyCmd create raw MultiSigAccOwnerDel transaction
// CreateMultiSigAccOwnerModifyCmd create raw MultiSigAccOwnerDel transaction
func
CreateMultiSigAccOwnerModifyCmd
()
*
cobra
.
Command
{
func
CreateMultiSigAccOwnerModifyCmd
()
*
cobra
.
Command
{
cmd
:=
&
cobra
.
Command
{
cmd
:=
&
cobra
.
Command
{
Use
:
"
owner_
modify"
,
Use
:
"modify"
,
Short
:
"Create a modify owner weight transaction"
,
Short
:
"Create a modify owner weight transaction"
,
Run
:
createOwnerModifyTransfer
,
Run
:
createOwnerModifyTransfer
,
}
}
...
@@ -273,7 +306,7 @@ func createOwnerModifyTransfer(cmd *cobra.Command, args []string) {
...
@@ -273,7 +306,7 @@ func createOwnerModifyTransfer(cmd *cobra.Command, args []string) {
// CreateMultiSigAccOwnerReplaceCmd create raw MultiSigAccOwnerReplace transaction
// CreateMultiSigAccOwnerReplaceCmd create raw MultiSigAccOwnerReplace transaction
func
CreateMultiSigAccOwnerReplaceCmd
()
*
cobra
.
Command
{
func
CreateMultiSigAccOwnerReplaceCmd
()
*
cobra
.
Command
{
cmd
:=
&
cobra
.
Command
{
cmd
:=
&
cobra
.
Command
{
Use
:
"
owner_
replace"
,
Use
:
"replace"
,
Short
:
"Create a replace owner transaction"
,
Short
:
"Create a replace owner transaction"
,
Run
:
createOwnerReplaceTransfer
,
Run
:
createOwnerReplaceTransfer
,
}
}
...
@@ -311,7 +344,7 @@ func createOwnerReplaceTransfer(cmd *cobra.Command, args []string) {
...
@@ -311,7 +344,7 @@ func createOwnerReplaceTransfer(cmd *cobra.Command, args []string) {
// CreateMultiSigAccWeightModifyCmd create raw CreateMultiSigAccWeightModifyCmd transaction
// CreateMultiSigAccWeightModifyCmd create raw CreateMultiSigAccWeightModifyCmd transaction
func
CreateMultiSigAccWeightModifyCmd
()
*
cobra
.
Command
{
func
CreateMultiSigAccWeightModifyCmd
()
*
cobra
.
Command
{
cmd
:=
&
cobra
.
Command
{
cmd
:=
&
cobra
.
Command
{
Use
:
"weight
_modify
"
,
Use
:
"weight"
,
Short
:
"Create a modify required weight transaction"
,
Short
:
"Create a modify required weight transaction"
,
Run
:
createMultiSigAccWeightModifyTransfer
,
Run
:
createMultiSigAccWeightModifyTransfer
,
}
}
...
@@ -552,7 +585,7 @@ func createMultiSigAccTransferOut(cmd *cobra.Command, args []string) {
...
@@ -552,7 +585,7 @@ func createMultiSigAccTransferOut(cmd *cobra.Command, args []string) {
//GetMultiSigAccCountCmd 获取已经创建的多重签名账户数量
//GetMultiSigAccCountCmd 获取已经创建的多重签名账户数量
func
GetMultiSigAccCountCmd
()
*
cobra
.
Command
{
func
GetMultiSigAccCountCmd
()
*
cobra
.
Command
{
cmd
:=
&
cobra
.
Command
{
cmd
:=
&
cobra
.
Command
{
Use
:
"
get_account_
count"
,
Use
:
"count"
,
Short
:
"get multisig account count"
,
Short
:
"get multisig account count"
,
Run
:
getMultiSigAccCount
,
Run
:
getMultiSigAccCount
,
}
}
...
@@ -577,8 +610,8 @@ func getMultiSigAccCount(cmd *cobra.Command, args []string) {
...
@@ -577,8 +610,8 @@ func getMultiSigAccCount(cmd *cobra.Command, args []string) {
//GetMultiSigAccountsCmd 获取已经创建的多重签名账户地址,通过转入的index
//GetMultiSigAccountsCmd 获取已经创建的多重签名账户地址,通过转入的index
func
GetMultiSigAccountsCmd
()
*
cobra
.
Command
{
func
GetMultiSigAccountsCmd
()
*
cobra
.
Command
{
cmd
:=
&
cobra
.
Command
{
cmd
:=
&
cobra
.
Command
{
Use
:
"
get_account
s"
,
Use
:
"
addres
s"
,
Short
:
"get multisig accounts"
,
Short
:
"get multisig account
addres
s"
,
Run
:
getMultiSigAccounts
,
Run
:
getMultiSigAccounts
,
}
}
addgetMultiSigAccountsFlags
(
cmd
)
addgetMultiSigAccountsFlags
(
cmd
)
...
@@ -623,7 +656,7 @@ func getMultiSigAccounts(cmd *cobra.Command, args []string) {
...
@@ -623,7 +656,7 @@ func getMultiSigAccounts(cmd *cobra.Command, args []string) {
//GetMultiSigAccountInfoCmd 获取已经创建的多重签名账户信息
//GetMultiSigAccountInfoCmd 获取已经创建的多重签名账户信息
func
GetMultiSigAccountInfoCmd
()
*
cobra
.
Command
{
func
GetMultiSigAccountInfoCmd
()
*
cobra
.
Command
{
cmd
:=
&
cobra
.
Command
{
cmd
:=
&
cobra
.
Command
{
Use
:
"
get_acc_
info"
,
Use
:
"info"
,
Short
:
"get multisig account info"
,
Short
:
"get multisig account info"
,
Run
:
getMultiSigAccountInfo
,
Run
:
getMultiSigAccountInfo
,
}
}
...
@@ -689,7 +722,7 @@ func parseAccInfo(view interface{}) (interface{}, error) {
...
@@ -689,7 +722,7 @@ func parseAccInfo(view interface{}) (interface{}, error) {
//GetMultiSigAccTxCountCmd 获取多重签名账户上的tx交易数量
//GetMultiSigAccTxCountCmd 获取多重签名账户上的tx交易数量
func
GetMultiSigAccTxCountCmd
()
*
cobra
.
Command
{
func
GetMultiSigAccTxCountCmd
()
*
cobra
.
Command
{
cmd
:=
&
cobra
.
Command
{
cmd
:=
&
cobra
.
Command
{
Use
:
"
get_tx_
count"
,
Use
:
"count"
,
Short
:
"get multisig tx count"
,
Short
:
"get multisig tx count"
,
Run
:
getMultiSigAccTxCount
,
Run
:
getMultiSigAccTxCount
,
}
}
...
@@ -724,7 +757,7 @@ func getMultiSigAccTxCount(cmd *cobra.Command, args []string) {
...
@@ -724,7 +757,7 @@ func getMultiSigAccTxCount(cmd *cobra.Command, args []string) {
//GetMultiSigTxidsCmd 获取多重签名账户上的tx交易数量
//GetMultiSigTxidsCmd 获取多重签名账户上的tx交易数量
func
GetMultiSigTxidsCmd
()
*
cobra
.
Command
{
func
GetMultiSigTxidsCmd
()
*
cobra
.
Command
{
cmd
:=
&
cobra
.
Command
{
cmd
:=
&
cobra
.
Command
{
Use
:
"
get_
txids"
,
Use
:
"txids"
,
Short
:
"get multisig txids"
,
Short
:
"get multisig txids"
,
Run
:
getMultiSigTxids
,
Run
:
getMultiSigTxids
,
}
}
...
@@ -795,7 +828,7 @@ func getMultiSigTxids(cmd *cobra.Command, args []string) {
...
@@ -795,7 +828,7 @@ func getMultiSigTxids(cmd *cobra.Command, args []string) {
//GetMultiSigTxInfoCmd 获取已经创建的多重签名账户的交易信息
//GetMultiSigTxInfoCmd 获取已经创建的多重签名账户的交易信息
func
GetMultiSigTxInfoCmd
()
*
cobra
.
Command
{
func
GetMultiSigTxInfoCmd
()
*
cobra
.
Command
{
cmd
:=
&
cobra
.
Command
{
cmd
:=
&
cobra
.
Command
{
Use
:
"
get_tx_
info"
,
Use
:
"info"
,
Short
:
"get multisig account tx info"
,
Short
:
"get multisig account tx info"
,
Run
:
getMultiSigTxInfo
,
Run
:
getMultiSigTxInfo
,
}
}
...
@@ -835,7 +868,7 @@ func getMultiSigTxInfo(cmd *cobra.Command, args []string) {
...
@@ -835,7 +868,7 @@ func getMultiSigTxInfo(cmd *cobra.Command, args []string) {
//GetMultiSigTxConfirmedWeightCmd 获取交易已经被确认的总权重
//GetMultiSigTxConfirmedWeightCmd 获取交易已经被确认的总权重
func
GetMultiSigTxConfirmedWeightCmd
()
*
cobra
.
Command
{
func
GetMultiSigTxConfirmedWeightCmd
()
*
cobra
.
Command
{
cmd
:=
&
cobra
.
Command
{
cmd
:=
&
cobra
.
Command
{
Use
:
"
get_
confirmed_weight"
,
Use
:
"confirmed_weight"
,
Short
:
"get the weight of the transaction confirmed."
,
Short
:
"get the weight of the transaction confirmed."
,
Run
:
getGetMultiSigTxConfirmedWeight
,
Run
:
getGetMultiSigTxConfirmedWeight
,
}
}
...
@@ -875,7 +908,7 @@ func getGetMultiSigTxConfirmedWeight(cmd *cobra.Command, args []string) {
...
@@ -875,7 +908,7 @@ func getGetMultiSigTxConfirmedWeight(cmd *cobra.Command, args []string) {
//GetMultiSigAccUnSpentTodayCmd 获取多重签名账户今日免多重签名的余额
//GetMultiSigAccUnSpentTodayCmd 获取多重签名账户今日免多重签名的余额
func
GetMultiSigAccUnSpentTodayCmd
()
*
cobra
.
Command
{
func
GetMultiSigAccUnSpentTodayCmd
()
*
cobra
.
Command
{
cmd
:=
&
cobra
.
Command
{
cmd
:=
&
cobra
.
Command
{
Use
:
"
get_
unspent"
,
Use
:
"unspent"
,
Short
:
"get assets unspent today amount"
,
Short
:
"get assets unspent today amount"
,
Run
:
getMultiSigAccUnSpentToday
,
Run
:
getMultiSigAccUnSpentToday
,
}
}
...
@@ -948,7 +981,7 @@ func parseUnSpentToday(view interface{}) (interface{}, error) {
...
@@ -948,7 +981,7 @@ func parseUnSpentToday(view interface{}) (interface{}, error) {
//GetMultiSigAccAssetsCmd 获取多重签名账户上的资产信息
//GetMultiSigAccAssetsCmd 获取多重签名账户上的资产信息
func
GetMultiSigAccAssetsCmd
()
*
cobra
.
Command
{
func
GetMultiSigAccAssetsCmd
()
*
cobra
.
Command
{
cmd
:=
&
cobra
.
Command
{
cmd
:=
&
cobra
.
Command
{
Use
:
"
get_
assets"
,
Use
:
"assets"
,
Short
:
"get assets of multisig account"
,
Short
:
"get assets of multisig account"
,
Run
:
getMultiSigAccAssets
,
Run
:
getMultiSigAccAssets
,
}
}
...
@@ -1028,7 +1061,7 @@ func parseAccAssets(view interface{}) (interface{}, error) {
...
@@ -1028,7 +1061,7 @@ func parseAccAssets(view interface{}) (interface{}, error) {
//GetMultiSigAccAllAddressCmd 获取指定地址创建的所有多重签名账户
//GetMultiSigAccAllAddressCmd 获取指定地址创建的所有多重签名账户
func
GetMultiSigAccAllAddressCmd
()
*
cobra
.
Command
{
func
GetMultiSigAccAllAddressCmd
()
*
cobra
.
Command
{
cmd
:=
&
cobra
.
Command
{
cmd
:=
&
cobra
.
Command
{
Use
:
"
get_cre_accounts
"
,
Use
:
"
creater
"
,
Short
:
"get all multisig accounts created by the address"
,
Short
:
"get all multisig accounts created by the address"
,
Run
:
getMultiSigAccAllAddress
,
Run
:
getMultiSigAccAllAddress
,
}
}
...
...
plugin/dapp/multisig/executor/multisig.go
View file @
c989cfb0
...
@@ -84,42 +84,32 @@ func (m *MultiSig) CheckTx(tx *types.Transaction, index int) error {
...
@@ -84,42 +84,32 @@ func (m *MultiSig) CheckTx(tx *types.Transaction, index int) error {
//MultiSigAccCreate 交易校验
//MultiSigAccCreate 交易校验
if
ato
,
ok
:=
payload
.
(
*
mty
.
MultiSigAccCreate
);
ok
{
if
ato
,
ok
:=
payload
.
(
*
mty
.
MultiSigAccCreate
);
ok
{
err
:=
checkAccountCreateTx
(
ato
)
return
checkAccountCreateTx
(
ato
)
if
err
!=
nil
{
return
err
}
}
}
//MultiSigOwnerOperate 交易的检测
//MultiSigOwnerOperate 交易的检测
if
ato
,
ok
:=
payload
.
(
*
mty
.
MultiSigOwnerOperate
);
ok
{
if
ato
,
ok
:=
payload
.
(
*
mty
.
MultiSigOwnerOperate
);
ok
{
err
:=
checkOwnerOperateTx
(
ato
)
return
checkOwnerOperateTx
(
ato
)
if
err
!=
nil
{
return
err
}
}
}
//MultiSigAccOperate
to 地址
检测
//MultiSigAccOperate
交易的
检测
if
ato
,
ok
:=
payload
.
(
*
mty
.
MultiSigAccOperate
);
ok
{
if
ato
,
ok
:=
payload
.
(
*
mty
.
MultiSigAccOperate
);
ok
{
err
:=
checkAccountOperateTx
(
ato
)
return
checkAccountOperateTx
(
ato
)
if
err
!=
nil
{
return
err
}
}
}
//MultiSigConfirmTx
multiSigAccAddr地址
检测
//MultiSigConfirmTx
交易的
检测
if
ato
,
ok
:=
payload
.
(
*
mty
.
MultiSigConfirmTx
);
ok
{
if
ato
,
ok
:=
payload
.
(
*
mty
.
MultiSigConfirmTx
);
ok
{
if
err
:=
address
.
CheckAddress
(
ato
.
GetMultiSigAccAddr
());
err
!=
nil
{
if
err
:=
address
.
CheckAddress
(
ato
.
GetMultiSigAccAddr
());
err
!=
nil
{
return
types
.
ErrInvalidAddress
return
types
.
ErrInvalidAddress
}
}
return
nil
}
}
//MultiSigExecTransfer
to 地址
检测
//MultiSigExecTransfer
交易的
检测
if
ato
,
ok
:=
payload
.
(
*
mty
.
MultiSigExecTransfer
);
ok
{
if
ato
,
ok
:=
payload
.
(
*
mty
.
MultiSigExecTransfer
);
ok
{
if
err
:=
address
.
CheckAddress
(
ato
.
GetTo
());
err
!=
nil
{
if
err
:=
address
.
CheckAddress
(
ato
.
GetTo
());
err
!=
nil
{
return
types
.
ErrInvalidAddress
return
types
.
ErrInvalidAddress
}
}
//assets check
//assets check
if
err
:=
mty
.
IsAssetsInvalid
(
ato
.
GetExecname
(),
ato
.
GetSymbol
());
err
!=
nil
{
return
mty
.
IsAssetsInvalid
(
ato
.
GetExecname
(),
ato
.
GetSymbol
())
return
err
}
}
}
return
nil
return
nil
}
}
...
@@ -167,10 +157,7 @@ func checkAccountCreateTx(ato *mty.MultiSigAccCreate) error {
...
@@ -167,10 +157,7 @@ func checkAccountCreateTx(ato *mty.MultiSigAccCreate) error {
dailyLimit
:=
ato
.
GetDailyLimit
()
dailyLimit
:=
ato
.
GetDailyLimit
()
//assets check
//assets check
if
err
:=
mty
.
IsAssetsInvalid
(
dailyLimit
.
GetExecer
(),
dailyLimit
.
GetSymbol
());
err
!=
nil
{
return
mty
.
IsAssetsInvalid
(
dailyLimit
.
GetExecer
(),
dailyLimit
.
GetSymbol
())
return
err
}
return
nil
}
}
func
checkOwnerOperateTx
(
ato
*
mty
.
MultiSigOwnerOperate
)
error
{
func
checkOwnerOperateTx
(
ato
*
mty
.
MultiSigOwnerOperate
)
error
{
...
@@ -229,9 +216,7 @@ func checkAccountOperateTx(ato *mty.MultiSigAccOperate) error {
...
@@ -229,9 +216,7 @@ func checkAccountOperateTx(ato *mty.MultiSigAccOperate) error {
if
ato
.
OperateFlag
==
mty
.
AccDailyLimitOp
{
if
ato
.
OperateFlag
==
mty
.
AccDailyLimitOp
{
dailyLimit
:=
ato
.
GetDailyLimit
()
dailyLimit
:=
ato
.
GetDailyLimit
()
//assets check
//assets check
if
err
:=
mty
.
IsAssetsInvalid
(
dailyLimit
.
GetExecer
(),
dailyLimit
.
GetSymbol
());
err
!=
nil
{
return
mty
.
IsAssetsInvalid
(
dailyLimit
.
GetExecer
(),
dailyLimit
.
GetSymbol
())
return
err
}
}
}
return
nil
return
nil
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment