Commit 3ef9413b authored by jiangpeng's avatar jiangpeng

privacy:support multiple asset in exec query

* update ShowAmountsOfUTXO and ShowUTXOs4SpecifiedAmount
parent fe44a8a1
syntax = "proto3";
package types;
//CycleBoundaryInfo cycle边界信息
message CycleBoundaryInfo{
int64 cycle = 1;
int64 stopHeight = 2;
string stopHash = 3;
// CycleBoundaryInfo cycle边界信息
message CycleBoundaryInfo {
int64 cycle = 1;
int64 stopHeight = 2;
string stopHash = 3;
}
//SuperNode 超级节点信息
message SuperNode{
bytes address = 1;
bytes pubKey = 2;
// SuperNode 超级节点信息
message SuperNode {
bytes address = 1;
bytes pubKey = 2;
}
//VoteItem 投票信息
// VoteItem 投票信息
message VoteItem {
int32 votedNodeIndex = 1; //被投票的节点索引
bytes votedNodeAddress = 2; //被投票的节点地址
int64 cycle = 3; //大周期序号
int64 cycleStart = 4; //大周期起始时间
int64 cycleStop = 5; //大周期终止时间
int64 periodStart = 6; //新节点负责出块的起始时间
int64 periodStop = 7; //新节点负责出块的终止时间
int64 height = 8; //新节点负责出块的起始高度
bytes voteID = 9; //选票ID
CycleBoundaryInfo lastCBInfo = 10;
int64 shuffleType = 11;
repeated SuperNode validators = 12;
repeated SuperNode vrfValidators = 13;
int32 votedNodeIndex = 1; //被投票的节点索引
bytes votedNodeAddress = 2; //被投票的节点地址
int64 cycle = 3; //大周期序号
int64 cycleStart = 4; //大周期起始时间
int64 cycleStop = 5; //大周期终止时间
int64 periodStart = 6; //新节点负责出块的起始时间
int64 periodStop = 7; //新节点负责出块的终止时间
int64 height = 8; //新节点负责出块的起始高度
bytes voteID = 9; //选票ID
CycleBoundaryInfo lastCBInfo = 10;
int64 shuffleType = 11;
repeated SuperNode validators = 12;
repeated SuperNode vrfValidators = 13;
repeated SuperNode noVrfValidators = 14;
}
//DPosVote Dpos共识的节点投票,为达成共识用。
// DPosVote Dpos共识的节点投票,为达成共识用。
message DPosVote {
VoteItem voteItem = 1;
int64 voteTimestamp = 2; //发起投票的时间
int32 voterNodeIndex = 3; //投票节点索引
bytes voterNodeAddress = 4; //投票节点地址
bytes signature = 5; //投票者签名
VoteItem voteItem = 1;
int64 voteTimestamp = 2; //发起投票的时间
int32 voterNodeIndex = 3; //投票节点索引
bytes voterNodeAddress = 4; //投票节点地址
bytes signature = 5; //投票者签名
}
//DPosVoteReply 投票响应。
// DPosVoteReply 投票响应。
message DPosVoteReply {
DPosVote vote = 1;
DPosVote vote = 1;
}
//DPosNotify Dpos委托节点出块周期结束时,通知其他节点进行高度确认及新节点投票。
// DPosNotify Dpos委托节点出块周期结束时,通知其他节点进行高度确认及新节点投票。
message DPosNotify {
VoteItem vote = 1;
int64 heightStop = 2; //新节点负责出块的结束高度
bytes hashStop = 3; //新节点负责出块的结束hash
int64 notifyTimestamp = 4; //发起通知的时间
int32 notifyNodeIndex = 5; //通知节点的索引
bytes notifyNodeAddress= 6; //通知节点的地址
bytes signature = 7; //通知节点的签名
VoteItem vote = 1;
int64 heightStop = 2; //新节点负责出块的结束高度
bytes hashStop = 3; //新节点负责出块的结束hash
int64 notifyTimestamp = 4; //发起通知的时间
int32 notifyNodeIndex = 5; //通知节点的索引
bytes notifyNodeAddress = 6; //通知节点的地址
bytes signature = 7; //通知节点的签名
}
//DPosCBInfo Cycle boundary注册信息。
// DPosCBInfo Cycle boundary注册信息。
message DPosCBInfo {
int64 cycle = 1;
int64 stopHeight = 2;
string stopHash = 3;
string pubkey = 4;
string signature = 5;
int64 cycle = 1;
int64 stopHeight = 2;
string stopHash = 3;
string pubkey = 4;
string signature = 5;
}
\ No newline at end of file
......@@ -4,7 +4,7 @@
syntax = "proto3";
//import "common.proto";
// import "common.proto";
import "board.proto";
import "project.proto";
import "rule.proto";
......@@ -27,13 +27,13 @@ message AutonomyAction {
PubVoteProposalProject pubVotePropProject = 8;
TerminateProposalProject tmintPropProject = 9;
// 提案规则修改相关
ProposalRule propRule = 10;
RevokeProposalRule rvkPropRule = 11;
VoteProposalRule votePropRule = 12;
TerminateProposalRule tmintPropRule = 13;
ProposalRule propRule = 10;
RevokeProposalRule rvkPropRule = 11;
VoteProposalRule votePropRule = 12;
TerminateProposalRule tmintPropRule = 13;
// 发展基金转自治系统合约
TransferFund transfer = 14;
Comment commentProp = 15;
TransferFund transfer = 14;
Comment commentProp = 15;
// 提案改变董事会成员
ProposalChange propChange = 16;
RevokeProposalChange rvkPropChange = 17;
......
......@@ -8,21 +8,20 @@ import "lcommon.proto";
package types;
message AutonomyProposalBoard {
ProposalBoard propBoard = 1;
ProposalBoard propBoard = 1;
// 投票该提案的规则
RuleConfig curRule = 2;
RuleConfig curRule = 2;
// 投票董事会
ActiveBoard board = 3;
ActiveBoard board = 3;
// 全体持票人投票结果
VoteResult voteResult = 4;
VoteResult voteResult = 4;
// 状态
int32 status = 5;
string address = 6;
int64 height = 7;
int32 index = 8;
string proposalID = 9;
int32 status = 5;
string address = 6;
int64 height = 7;
int32 index = 8;
string proposalID = 9;
}
// action
......@@ -37,9 +36,9 @@ message ProposalBoard {
// 提案董事会成员
repeated string boards = 5;
// 投票相关
// 投票相关
int64 startBlockHeight = 6; // 提案开始投票高度
int64 endBlockHeight = 7; // 提案结束投票高度
int64 endBlockHeight = 7; // 提案结束投票高度
int64 realEndBlockHeight = 8; // 实际提案结束投票高度
}
......@@ -48,8 +47,8 @@ message RevokeProposalBoard {
}
message VoteProposalBoard {
string proposalID = 1;
bool approve = 2;
string proposalID = 1;
bool approve = 2;
repeated string originAddr = 3;
}
......@@ -79,5 +78,5 @@ message ReqQueryProposalBoard {
}
message ReplyQueryProposalBoard {
repeated AutonomyProposalBoard propBoards = 1;
repeated AutonomyProposalBoard propBoards = 1;
}
\ No newline at end of file
......@@ -8,21 +8,20 @@ import "lcommon.proto";
package types;
message AutonomyProposalChange {
ProposalChange propChange = 1;
ProposalChange propChange = 1;
// 投票该提案的规则
RuleConfig curRule = 2;
RuleConfig curRule = 2;
// 投票董事会
ActiveBoard board = 3;
ActiveBoard board = 3;
// 全体持票人投票结果
VoteResult voteResult = 4;
VoteResult voteResult = 4;
// 状态
int32 status = 5;
string address = 6;
int64 height = 7;
int32 index = 8;
string proposalID = 9;
int32 status = 5;
string address = 6;
int64 height = 7;
int32 index = 8;
string proposalID = 9;
}
// action
......@@ -33,11 +32,11 @@ message ProposalChange {
int32 day = 3;
// 修改董事会成员
repeated Change changes = 4;
repeated Change changes = 4;
// 投票相关
// 投票相关
int64 startBlockHeight = 5; // 提案开始投票高度
int64 endBlockHeight = 6; // 提案结束投票高度
int64 endBlockHeight = 6; // 提案结束投票高度
int64 realEndBlockHeight = 7; // 实际提案结束投票高度
}
......@@ -68,7 +67,7 @@ message ReceiptProposalChange {
message LocalProposalChange {
AutonomyProposalChange propBd = 1;
repeated string comments = 2;
repeated string comments = 2;
}
// query
......@@ -82,5 +81,5 @@ message ReqQueryProposalChange {
}
message ReplyQueryProposalChange {
repeated AutonomyProposalChange propChanges = 1;
repeated AutonomyProposalChange propChanges = 1;
}
\ No newline at end of file
......@@ -8,24 +8,24 @@ package types;
message VoteResult {
// 总票数
int32 totalVotes = 1;
int32 totalVotes = 1;
// 赞成票
int32 approveVotes = 2;
int32 approveVotes = 2;
// 反对票
int32 opposeVotes = 3;
int32 opposeVotes = 3;
// 是否通过
bool pass = 4;
bool pass = 4;
}
message PublicVote {
// 是否需要公示
bool publicity = 1;
bool publicity = 1;
// 总票数
int32 totalVotes = 2;
int32 totalVotes = 2;
// 全体持票人反对票
int32 opposeVotes = 3;
int32 opposeVotes = 3;
// 是否通过
bool pubPass = 4;
bool pubPass = 4;
}
message VotesRecord {
......@@ -34,15 +34,15 @@ message VotesRecord {
message RuleConfig {
// 董事会成员赞成率,以%为单位,只保留整数部分
int32 boardApproveRatio = 1;
int32 boardApproveRatio = 1;
// 全体持票人否决率
int32 pubOpposeRatio = 2;
int32 pubOpposeRatio = 2;
// 提案金额
int64 proposalAmount = 3;
int64 proposalAmount = 3;
// 重大项目公示金额阈值
int64 largeProjectAmount = 4;
int64 largeProjectAmount = 4;
// 重大项目公示时间(以区块数为单位)
int32 publicPeriod = 5;
int32 publicPeriod = 5;
}
message ActiveBoard {
......
......@@ -9,21 +9,21 @@ import "lcommon.proto";
package types;
message AutonomyProposalProject {
ProposalProject propProject = 1;
ProposalProject propProject = 1;
// 投票该提案的规则
RuleConfig curRule = 2;
RuleConfig curRule = 2;
// 投票该提案的董事会成员
repeated string boards = 3;
repeated string boards = 3;
// 董事会投票结果
VoteResult boardVoteRes = 4;
VoteResult boardVoteRes = 4;
// 公示投票
PublicVote pubVote = 5;
PublicVote pubVote = 5;
// 状态
int32 status = 6;
string address = 7;
int64 height = 8;
int32 index = 9;
string proposalID = 10;
int32 status = 6;
string address = 7;
int64 height = 8;
int32 index = 9;
string proposalID = 10;
}
message ProposalProject {
......@@ -42,7 +42,7 @@ message ProposalProject {
string amountDetail = 10; // 经费细则
// 支付相关
string toAddr = 11; // 收款地址
string toAddr = 11; // 收款地址
// 投票相关
int64 startBlockHeight = 12; // 提案开始投票高度
......@@ -61,8 +61,8 @@ message VoteProposalProject {
}
message PubVoteProposalProject {
string proposalID = 1;
bool oppose = 2;
string proposalID = 1;
bool oppose = 2;
repeated string originAddr = 3;
}
......@@ -77,8 +77,8 @@ message ReceiptProposalProject {
}
message LocalProposalProject {
AutonomyProposalProject propPrj = 1;
repeated string comments = 2;
AutonomyProposalProject propPrj = 1;
repeated string comments = 2;
}
// query
......
......@@ -9,16 +9,16 @@ import "lcommon.proto";
package types;
message AutonomyProposalRule {
ProposalRule propRule = 1;
RuleConfig curRule = 2;
ProposalRule propRule = 1;
RuleConfig curRule = 2;
// 全体持票人投票结果
VoteResult voteResult = 3;
VoteResult voteResult = 3;
// 状态
int32 status = 4;
string address = 5;
int64 height = 6;
int32 index = 7;
string proposalID = 8;
int32 status = 4;
string address = 5;
int64 height = 6;
int32 index = 7;
string proposalID = 8;
}
message ProposalRule {
......@@ -28,7 +28,7 @@ message ProposalRule {
int32 day = 3;
// 规则可修改项,如果某项不修改则置为-1
RuleConfig ruleCfg = 4;
RuleConfig ruleCfg = 4;
// 投票相关
int64 startBlockHeight = 5; // 提案开始投票高度
int64 endBlockHeight = 6; // 提案结束投票高度
......@@ -40,8 +40,8 @@ message RevokeProposalRule {
}
message VoteProposalRule {
string proposalID = 1;
bool approve = 2;
string proposalID = 1;
bool approve = 2;
repeated string originAddr = 3;
}
......@@ -51,13 +51,13 @@ message TerminateProposalRule {
// receipt
message ReceiptProposalRule {
AutonomyProposalRule prev = 1;
AutonomyProposalRule current = 2;
AutonomyProposalRule prev = 1;
AutonomyProposalRule current = 2;
}
message LocalProposalRule {
AutonomyProposalRule propRule = 1;
repeated string comments = 2;
repeated string comments = 2;
}
// query
......@@ -76,8 +76,8 @@ message ReplyQueryProposalRule {
// TransferFund action
message TransferFund {
int64 amount = 1;
string note = 2;
int64 amount = 1;
string note = 2;
}
// Comment action
......
This diff is collapsed.
......@@ -3,38 +3,38 @@ package echo;
// ping操作action
message Ping {
string msg = 1;
string msg = 1;
}
// pang操作action
message Pang {
string msg = 1;
string msg = 1;
}
// 本执行器的统一Action结构
message EchoAction {
oneof value {
Ping ping = 1;
Pang pang = 2;
Ping ping = 1;
Pang pang = 2;
}
int32 ty = 3;
}
// ping操作生成的日志结构
message PingLog {
string msg = 1;
string echo = 2;
int32 count = 3;
string msg = 1;
string echo = 2;
int32 count = 3;
}
// pang操作生成的日志结构
message PangLog {
string msg = 1;
string echo = 2;
int32 count = 3;
string msg = 1;
string echo = 2;
int32 count = 3;
}
// 查询请求结构
message Query {
string msg = 1;
string msg = 1;
}
// 查询结果结构
message QueryResult {
string msg = 1;
int32 count = 2;
string msg = 1;
int32 count = 2;
}
\ No newline at end of file
......@@ -149,33 +149,33 @@ message EvmQueryResp {
}
message EvmContractCreateReq {
string code = 1;
int64 fee = 2;
string note = 3;
string alias = 4;
string caller = 5;
string abi = 6;
string expire = 7;
string paraName = 8;
string code = 1;
int64 fee = 2;
string note = 3;
string alias = 4;
string caller = 5;
string abi = 6;
string expire = 7;
string paraName = 8;
}
message EvmContractCallReq {
uint64 amount = 1;
string code = 2;
int64 fee = 3;
string note = 4;
string caller = 5;
string abi = 6;
string exec = 7;
string expire = 8;
string paraName = 9;
uint64 amount = 1;
string code = 2;
int64 fee = 3;
string note = 4;
string caller = 5;
string abi = 6;
string exec = 7;
string expire = 8;
string paraName = 9;
}
message EvmContractTransferReq {
string caller = 1;
float amount = 2;
string exec = 3;
string expire = 4;
bool isWithdraw = 5;
string paraName = 6;
string caller = 1;
float amount = 2;
string exec = 3;
string expire = 4;
bool isWithdraw = 5;
string paraName = 6;
}
\ No newline at end of file
syntax = "proto3";
package types;
message Exchange {
}
message Exchange {}
message ExchangeAction {
oneof value {
LimitOrder limitOrder = 1;
LimitOrder limitOrder = 1;
MarketOrder marketOrder = 2;
RevokeOrder revokeOrder = 3;
}
......@@ -15,11 +14,11 @@ message ExchangeAction {
//限价订单
message LimitOrder {
//交易对
asset leftAsset = 1;
asset leftAsset = 1;
//交易对
asset rightAsset = 2;
asset rightAsset = 2;
//价格
int64 price = 3;
int64 price = 3;
//总量
int64 amount = 4;
//操作, 1为买,2为卖
......@@ -29,7 +28,7 @@ message LimitOrder {
//市价委托
message MarketOrder {
//资产1
asset leftAsset = 1;
asset leftAsset = 1;
//资产2
asset rightAsset = 2;
//总量
......@@ -41,7 +40,7 @@ message MarketOrder {
//撤回订单
message RevokeOrder {
//订单号
int64 orderID = 1;
int64 orderID = 1;
}
//资产类型
message asset {
......@@ -51,9 +50,9 @@ message asset {
//订单信息
message Order {
int64 orderID = 1;
int64 orderID = 1;
oneof value {
LimitOrder limitOrder = 2;
LimitOrder limitOrder = 2;
MarketOrder marketOrder = 3;
}
//挂单类型
......@@ -63,7 +62,7 @@ message Order {
//成交均价
int64 AVG_price = 6;
//余额
int64 balance = 7;
int64 balance = 7;
//状态,0 挂单中ordered, 1 完成completed, 2撤回 revoked
int32 status = 8;
//用户地址
......@@ -77,24 +76,24 @@ message Order {
//查询接口
message QueryMarketDepth {
//资产1
asset leftAsset = 1;
asset leftAsset = 1;
//资产2
asset rightAsset = 2;
//操作, 1为买,2为卖
int32 op = 3;
// 这里用价格作为索引值
string primaryKey = 4;
string primaryKey = 4;
//单页返回多少条记录,默认返回10条,为了系统安全最多单次只能返回20条
int32 count = 5;
}
//市场深度
message MarketDepth {
//资产1
asset leftAsset = 1;
asset leftAsset = 1;
//资产2
asset rightAsset = 2;
//价格
int64 price = 3;
int64 price = 3;
//总量
int64 amount = 4;
//操作, 1为买,2为卖
......@@ -102,14 +101,14 @@ message MarketDepth {
}
//查询接口返回的市场深度列表
message MarketDepthList {
repeated MarketDepth list = 1;
string primaryKey = 2;
repeated MarketDepth list = 1;
string primaryKey = 2;
}
//查询最新得成交信息,外部接口
message QueryHistoryOrderList {
//资产1
asset leftAsset = 1;
asset leftAsset = 1;
//资产2
asset rightAsset = 2;
// 索引值
......@@ -122,7 +121,7 @@ message QueryHistoryOrderList {
//根据orderID去查询订单信息
message QueryOrder {
int64 orderID = 1;
int64 orderID = 1;
}
//根据地址,状态查询用户自己的挂单信息
message QueryOrderList {
......@@ -139,17 +138,14 @@ message QueryOrderList {
}
//订单列表
message OrderList {
repeated Order list = 1;
string primaryKey = 2;
repeated Order list = 1;
string primaryKey = 2;
}
//exchange执行票据日志
// exchange执行票据日志
message ReceiptExchange {
Order order = 1;
Order order = 1;
repeated Order matchOrders = 2;
int64 index = 3;
}
service exchange {
int64 index = 3;
}
service exchange {}
This diff is collapsed.
......@@ -4,54 +4,54 @@ package types;
// 发行信息
message Issuance {
string issuanceId = 1; //发行ID,一期发行对应一个ID
int64 totalBalance = 2; //当期发行的总金额(ccny)
int64 debtCeiling = 3; //单用户可借出的限额(ccny)
int64 liquidationRatio = 4; //清算比例
int64 collateralValue = 5; //抵押物总数量(bty)
int64 debtValue = 6; //产生的ccny数量
repeated DebtRecord debtRecords = 7; //大户抵押记录
repeated DebtRecord invalidRecords = 8; //大户抵押记录
int32 status = 9; //当期发行的状态,是否关闭
int64 latestLiquidationPrice = 10;//最高清算价格
int64 period = 11;//发行最大期限
int64 latestExpireTime = 12;//最近超期时间
int64 createTime = 13;//创建时间
int64 balance = 14;//剩余可发行ccny
string issuerAddr = 15;//发行地址
string issuanceId = 1; //发行ID,一期发行对应一个ID
int64 totalBalance = 2; //当期发行的总金额(ccny)
int64 debtCeiling = 3; //单用户可借出的限额(ccny)
int64 liquidationRatio = 4; //清算比例
int64 collateralValue = 5; //抵押物总数量(bty)
int64 debtValue = 6; //产生的ccny数量
repeated DebtRecord debtRecords = 7; //大户抵押记录
repeated DebtRecord invalidRecords = 8; //大户抵押记录
int32 status = 9; //当期发行的状态,是否关闭
int64 latestLiquidationPrice = 10; //最高清算价格
int64 period = 11; //发行最大期限
int64 latestExpireTime = 12; //最近超期时间
int64 createTime = 13; //创建时间
int64 balance = 14; //剩余可发行ccny
string issuerAddr = 15; //发行地址
}
// 抵押记录
message DebtRecord {
string accountAddr = 1; //抵押人地址
int64 startTime = 2; //抵押时间
int64 collateralValue = 3; //抵押物价值(bty)
int64 collateralPrice = 4; //抵押物价格
int64 debtValue = 5; //债务价值(ccny)
int64 liquidationPrice = 6; //抵押物清算价格
int32 status = 7; //抵押状态,是否被清算
int64 liquidateTime = 8; //清算时间
int64 expireTime = 9; //超时清算时间
int32 preStatus = 10;//上一次抵押状态,用于告警恢复
string debtId = 11;//借贷id
string issuId = 12;//发行id
string accountAddr = 1; //抵押人地址
int64 startTime = 2; //抵押时间
int64 collateralValue = 3; //抵押物价值(bty)
int64 collateralPrice = 4; //抵押物价格
int64 debtValue = 5; //债务价值(ccny)
int64 liquidationPrice = 6; //抵押物清算价格
int32 status = 7; //抵押状态,是否被清算
int64 liquidateTime = 8; //清算时间
int64 expireTime = 9; //超时清算时间
int32 preStatus = 10; //上一次抵押状态,用于告警恢复
string debtId = 11; //借贷id
string issuId = 12; //发行id
}
// 资产价格记录
message IssuanceAssetPriceRecord {
int64 recordTime = 1; //价格记录时间
int64 btyPrice = 2; //bty价格
int64 recordTime = 1; //价格记录时间
int64 btyPrice = 2; // bty价格
}
// action
message IssuanceAction {
oneof value {
IssuanceCreate create = 1; //创建一期发行
IssuanceDebt debt = 2; //抵押
IssuanceRepay repay = 3; //清算
IssuanceFeed feed = 4; //喂价
IssuanceClose close = 5; //关闭
IssuanceManage manage = 6; //全局配置
IssuanceCreate create = 1; //创建一期发行
IssuanceDebt debt = 2; //抵押
IssuanceRepay repay = 3; //清算
IssuanceFeed feed = 4; //喂价
IssuanceClose close = 5; //关闭
IssuanceManage manage = 6; //全局配置
}
int32 ty = 10;
}
......@@ -62,10 +62,10 @@ message IssuanceManage {
// 创建发行
message IssuanceCreate {
int64 totalBalance = 1; //发行总金额
int64 debtCeiling = 2; //单用户可借出的限额(ccny)
int64 liquidationRatio = 3; //清算比例
int64 period = 4; //发行最大期限
int64 totalBalance = 1; //发行总金额
int64 debtCeiling = 2; //单用户可借出的限额(ccny)
int64 liquidationRatio = 3; //清算比例
int64 period = 4; //发行最大期限
}
// 抵押
......@@ -82,9 +82,9 @@ message IssuanceRepay {
// 喂价
message IssuanceFeed {
int32 collType = 1; //抵押物价格类型(1,bty,2,btc,3,eth...)
repeated int64 price = 2; //喂价
repeated int64 volume = 3; //成交量
int32 collType = 1; //抵押物价格类型(1,bty,2,btc,3,eth...)
repeated int64 price = 2; //喂价
repeated int64 volume = 3; //成交量
}
// 借贷关闭
......@@ -94,16 +94,16 @@ message IssuanceClose {
// exec_local 发行信息
message ReceiptIssuance {
string issuanceId = 1;
string accountAddr = 2;
string debtId = 3;
int32 status = 4;
string issuanceId = 1;
string accountAddr = 2;
string debtId = 3;
int32 status = 4;
}
// exec_local issuid记录信息
message ReceiptIssuanceID {
string issuanceId = 1;
int32 status = 2;
string issuanceId = 1;
int32 status = 2;
}
// exec_local 抵押记录信息列表
......@@ -118,16 +118,16 @@ message ReqIssuanceInfo {
// 返回一期发行信息
message RepIssuanceCurrentInfo {
int32 status = 1; //当期发行的状态,是否关闭
int64 totalBalance = 2; //当期发行总金额(ccny)
int64 debtCeiling = 3; //单用户可借出的限额(ccny)
int64 liquidationRatio = 4; //清算比例
int64 balance = 5; //剩余可借贷金额(ccny)
int64 collateralValue = 6; //抵押物总数量(bty)
int64 debtValue = 7; //产生的ccny数量
int64 period = 8; //发行最大期限
string issuId = 9; //发行ID
int64 createTime = 10;//创建时间
int32 status = 1; //当期发行的状态,是否关闭
int64 totalBalance = 2; //当期发行总金额(ccny)
int64 debtCeiling = 3; //单用户可借出的限额(ccny)
int64 liquidationRatio = 4; //清算比例
int64 balance = 5; //剩余可借贷金额(ccny)
int64 collateralValue = 6; //抵押物总数量(bty)
int64 debtValue = 7; //产生的ccny数量
int64 period = 8; //发行最大期限
string issuId = 9; //发行ID
int64 createTime = 10; //创建时间
}
// 根据ID列表查询多期发行信息
......@@ -142,7 +142,7 @@ message RepIssuanceCurrentInfos {
// 根据发行状态查询
message ReqIssuanceByStatus {
int32 status = 1;
int32 status = 1;
string issuanceId = 2;
}
......@@ -155,7 +155,7 @@ message RepIssuanceIDs {
message ReqIssuanceRecords {
string issuanceId = 1;
string addr = 2;
int32 status = 3;
int32 status = 3;
string debtId = 4;
}
......
......@@ -9,15 +9,15 @@ message Create {
// call action
message Call {
string name = 1; //exec name
string funcname = 2; //call function name
string args = 3; //json args
string name = 1; // exec name
string funcname = 2; // call function name
string args = 3; // json args
}
message JsAction {
oneof value {
Create create = 1;
Call call = 2;
Create create = 1;
Call call = 2;
}
int32 ty = 3;
}
......
......@@ -17,28 +17,28 @@ message PurchaseRecords {
}
message Lottery {
string lotteryId = 1;
int32 status = 2;
int64 createHeight = 3;
int64 fund = 4;
int64 purBlockNum = 5;
int64 drawBlockNum = 6;
int64 lastTransToPurState = 7;
int64 lastTransToDrawState = 8;
//map<string, PurchaseRecords> records = 9;
int64 totalPurchasedTxNum = 10;
string createAddr = 11;
int64 round = 12;
int64 luckyNumber = 13;
int64 createOnMain = 14;
int64 lastTransToPurStateOnMain = 15;
int64 lastTransToDrawStateOnMain = 16;
repeated MissingRecord missingRecords = 17;
int64 opRewardRatio = 18;
int64 devRewardRatio = 19;
repeated PurchaseRecords purRecords = 20;
int64 totalAddrNum = 21;
int64 buyAmount = 22;
string lotteryId = 1;
int32 status = 2;
int64 createHeight = 3;
int64 fund = 4;
int64 purBlockNum = 5;
int64 drawBlockNum = 6;
int64 lastTransToPurState = 7;
int64 lastTransToDrawState = 8;
// map<string, PurchaseRecords> records = 9;
int64 totalPurchasedTxNum = 10;
string createAddr = 11;
int64 round = 12;
int64 luckyNumber = 13;
int64 createOnMain = 14;
int64 lastTransToPurStateOnMain = 15;
int64 lastTransToDrawStateOnMain = 16;
repeated MissingRecord missingRecords = 17;
int64 opRewardRatio = 18;
int64 devRewardRatio = 19;
repeated PurchaseRecords purRecords = 20;
int64 totalAddrNum = 21;
int64 buyAmount = 22;
}
message MissingRecord {
......@@ -152,8 +152,8 @@ message ReplyLotteryCurrentInfo {
int64 purBlockNum = 10;
int64 drawBlockNum = 11;
repeated MissingRecord missingRecords = 12;
int64 totalAddrNum = 13;
int64 buyAmount = 14;
int64 totalAddrNum = 13;
int64 buyAmount = 14;
}
message ReplyLotteryHistoryLuckyNumber {
......@@ -218,21 +218,21 @@ message ReplyLotteryPurchaseAddr {
repeated string address = 1;
}
message LotteryGainInfos{
message LotteryGainInfos {
repeated LotteryGainInfo gains = 1;
}
message LotteryGainInfo{
string addr = 1;
int64 buyAmount = 2;
int64 fundAmount = 3;
message LotteryGainInfo {
string addr = 1;
int64 buyAmount = 2;
int64 fundAmount = 3;
}
message LotteryGainRecord{
string addr = 1;
int64 buyAmount = 2;
int64 fundAmount = 3;
int64 round = 4;
message LotteryGainRecord {
string addr = 1;
int64 buyAmount = 2;
int64 fundAmount = 3;
int64 round = 4;
}
message LotteryGainRecords {
......@@ -252,4 +252,3 @@ message ReqLotteryGainInfo {
string addr = 2;
int64 round = 3;
}
This diff is collapsed.
......@@ -2,10 +2,10 @@ syntax = "proto3";
package types;
message Norm {
bytes normId = 1;
int64 createTime = 2;
bytes normId = 1;
int64 createTime = 2;
bytes key = 3;
bytes value = 4;
bytes value = 4;
}
message NormAction {
......@@ -17,7 +17,7 @@ message NormAction {
message NormPut {
bytes key = 1;
bytes value = 2;
bytes value = 2;
}
message NormGetKey {
......
......@@ -4,34 +4,34 @@ package types;
//事件
message OracleStatus {
string eventID = 1; //事件ID
string addr = 2; //发布者地址
string type = 3; //游戏类别
string subType = 4; //游戏子类别
int64 time = 5; //结果公布参考时间
string content = 6; //事件内容
string introduction = 7; //事件描述
EventStatus status = 8; //操作状态
string source = 9; //数据来源
string result = 10; //事件结果
EventStatus preStatus=11; //上次操作后状态及操作者地址
string eventID = 1; //事件ID
string addr = 2; //发布者地址
string type = 3; //游戏类别
string subType = 4; //游戏子类别
int64 time = 5; //结果公布参考时间
string content = 6; //事件内容
string introduction = 7; //事件描述
EventStatus status = 8; //操作状态
string source = 9; //数据来源
string result = 10; //事件结果
EventStatus preStatus = 11; //上次操作后状态及操作者地址
}
// action
message OracleAction {
oneof value {
EventPublish eventPublish = 1;
EventAbort eventAbort = 2;
ResultPrePublish resultPrePublish = 3;
ResultPublish resultPublish = 4;
ResultAbort resultAbort = 5;
EventPublish eventPublish = 1;
EventAbort eventAbort = 2;
ResultPrePublish resultPrePublish = 3;
ResultPublish resultPublish = 4;
ResultAbort resultAbort = 5;
}
int32 Ty = 7;
}
message EventStatus {
string opAddr = 1; //修改事件状态的地址
int32 status = 2; //事件状态
int32 status = 2; //事件状态
}
message EventPublish {
......@@ -43,23 +43,23 @@ message EventPublish {
}
message EventAbort {
string eventID = 2; //发布事件的ID
string eventID = 2; //发布事件的ID
}
message ResultPrePublish {
string eventID = 2; //发布事件的ID
string source = 3; //数据来源
string result = 4; //发布数据
string eventID = 2; //发布事件的ID
string source = 3; //数据来源
string result = 4; //发布数据
}
message ResultPublish {
string eventID = 2; //发布事件的ID
string source = 3; //数据来源
string result = 4; //发布数据
string eventID = 2; //发布事件的ID
string source = 3; //数据来源
string result = 4; //发布数据
}
message ResultAbort {
string eventID = 2; //发布事件的ID
string eventID = 2; //发布事件的ID
}
// localDB
......@@ -72,22 +72,22 @@ message QueryOracleInfos {
}
message ReplyEventIDs {
repeated string eventID = 1; //发布事件的ID
repeated string eventID = 1; //发布事件的ID
}
message QueryEventID {
int32 status = 1; //事件状态
string addr = 2; //事件发布者的地址
string type = 3; //事件类型
string eventID = 4; //事件ID
int32 status = 1; //事件状态
string addr = 2; //事件发布者的地址
string type = 3; //事件类型
string eventID = 4; //事件ID
}
message ReceiptOracle {
string eventID = 1; //发布事件ID
int32 status = 2; //事件状态
string addr = 3; //事件发布者的地址
string type = 4; //事件类型
int32 preStatus = 6;//事件的前一个状态
string eventID = 1; //发布事件ID
int32 status = 2; //事件状态
string addr = 3; //事件发布者的地址
string type = 4; //事件类型
int32 preStatus = 6; //事件的前一个状态
}
message ReplyOracleStatusList {
......
This diff is collapsed.
......@@ -4,40 +4,40 @@ package types;
//斗牛游戏内容
message PokerBull {
string gameId = 1; //默认是由创建这局游戏的txHash作为gameId
int32 status = 2; // Start 1 -> Continue 2 -> Quit 3
int64 startTime = 3; //开始时间
string startTxHash = 4; //游戏启动交易hash
int64 value = 5; //赌注
PBPoker poker = 6; //扑克牌
repeated PBPlayer players = 7; //玩家历史牌和结果集
int32 playerNum = 8; //玩家数
repeated PBResult results = 9; //游戏结果集
int64 index = 10; //索引
int64 prevIndex = 11; //上级索引
int64 quitTime = 12; //游戏结束时间
string quitTxHash = 13; //游戏结束交易hash
string dealerAddr = 14; //下局庄家地址
bool isWaiting = 15; //游戏是否处于等待状态
int32 preStatus = 16; //上一index的状态
int32 round = 17; //当前游戏回合数
string gameId = 1; //默认是由创建这局游戏的txHash作为gameId
int32 status = 2; // Start 1 -> Continue 2 -> Quit 3
int64 startTime = 3; //开始时间
string startTxHash = 4; //游戏启动交易hash
int64 value = 5; //赌注
PBPoker poker = 6; //扑克牌
repeated PBPlayer players = 7; //玩家历史牌和结果集
int32 playerNum = 8; //玩家数
repeated PBResult results = 9; //游戏结果集
int64 index = 10; //索引
int64 prevIndex = 11; //上级索引
int64 quitTime = 12; //游戏结束时间
string quitTxHash = 13; //游戏结束交易hash
string dealerAddr = 14; //下局庄家地址
bool isWaiting = 15; //游戏是否处于等待状态
int32 preStatus = 16; //上一index的状态
int32 round = 17; //当前游戏回合数
}
//一把牌
message PBHand {
repeated int32 cards = 1; //一把牌,五张
int32 result = 2; //斗牛结果 (没牛:0, 牛1-9:1-9, 牛牛:10)
string address = 3; //玩家地址
bool isWin = 4; //是否赢庄家
int32 leverage = 5; //赌注倍数
repeated int32 cards = 1; //一把牌,五张
int32 result = 2; //斗牛结果 (没牛:0, 牛1-9:1-9, 牛牛:10)
string address = 3; //玩家地址
bool isWin = 4; //是否赢庄家
int32 leverage = 5; //赌注倍数
}
//玩家
message PBPlayer {
repeated PBHand hands = 1; //历史发牌和斗牛结果
string address = 2; //玩家地址
int64 txHash = 3; //发牌随机数因子txhash的整数格式
bool ready = 4; //continue状态下,是否ready
repeated PBHand hands = 1; //历史发牌和斗牛结果
string address = 2; //玩家地址
int64 txHash = 3; //发牌随机数因子txhash的整数格式
bool ready = 4; // continue状态下,是否ready
}
//本局游戏结果
......@@ -58,11 +58,11 @@ message PBPoker {
//游戏状态
message PBGameAction {
oneof value {
PBGameStart start = 1;
PBGameStart start = 1;
PBGameContinue continue = 2;
PBGameQuit quit = 3;
PBGameQuery query = 4;
PBGamePlay play = 5;
PBGameQuit quit = 3;
PBGameQuery query = 4;
PBGamePlay play = 5;
}
int32 ty = 10;
}
......@@ -90,9 +90,9 @@ message PBGameQuery {
//已匹配玩家直接游戏
message PBGamePlay {
string gameId = 1; //游戏id
int32 round = 2; //当前游戏回合数
int64 value = 3; //当前游戏赌注
string gameId = 1; //游戏id
int32 round = 2; //当前游戏回合数
int64 value = 3; //当前游戏赌注
repeated string address = 4; //玩家地址
}
......@@ -150,13 +150,13 @@ message QueryPBGameByRound {
// ReplyPBGameByRound 某一回合游戏结果
message ReplyPBGameByRound {
string gameId = 1;
int32 status = 2;
PBResult result = 3;
bool isWaiting = 4;
int64 value = 5;
repeated PBPlayer players = 6;
int64 return = 7;
string gameId = 1;
int32 status = 2;
PBResult result = 3;
bool isWaiting = 4;
int64 value = 5;
repeated PBPlayer players = 6;
int64 return = 7;
}
message ReceiptPBGame {
......@@ -169,8 +169,8 @@ message ReceiptPBGame {
int64 value = 7;
bool isWaiting = 8;
repeated string players = 9;
int32 preStatus = 10;
int32 round = 11;
int32 preStatus = 10;
int32 round = 11;
}
message PBStartTxReq {
......@@ -193,4 +193,3 @@ message PBQueryReq {
string gameId = 1;
int64 fee = 2;
}
......@@ -356,12 +356,16 @@ func showAmountsOfUTXOCmd() *cobra.Command {
}
func showAmountOfUTXOFlag(cmd *cobra.Command) {
cmd.Flags().StringP("symbol", "s", "BTY", "asset symbol, default BTY")
cmd.Flags().StringP("exec", "e", "coins", "asset executor(coins, token, paracross), default coins")
}
func showAmountOfUTXO(cmd *cobra.Command, args []string) {
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
reqPrivacyToken := pty.ReqPrivacyToken{Token: types.BTY}
exec, _ := cmd.Flags().GetString("exec")
symbol, _ := cmd.Flags().GetString("symbol")
reqPrivacyToken := pty.ReqPrivacyToken{AssetExec: exec, AssetSymbol: symbol}
var params rpctypes.Query4Jrpc
params.Execer = pty.PrivacyX
params.FuncName = "ShowAmountsOfUTXO"
......@@ -394,16 +398,20 @@ func showUTXOs4SpecifiedAmountCmd() *cobra.Command {
func showUTXOs4SpecifiedAmountFlag(cmd *cobra.Command) {
cmd.Flags().Float64P("amount", "a", 0, "amount")
cmd.MarkFlagRequired("amount")
cmd.Flags().StringP("exec", "e", "coins", "asset executor(coins, token, paracross), default coins")
cmd.Flags().StringP("symbol", "s", "BTY", "asset symbol, default BTY")
}
func showUTXOs4SpecifiedAmount(cmd *cobra.Command, args []string) {
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
amount, _ := cmd.Flags().GetFloat64("amount")
amountInt64 := int64(amount*types.InputPrecision) * types.Multiple1E4
exec, _ := cmd.Flags().GetString("exec")
symbol, _ := cmd.Flags().GetString("symbol")
reqPrivacyToken := pty.ReqPrivacyToken{
Token: types.BTY,
Amount: amountInt64,
AssetExec: exec,
AssetSymbol: symbol,
Amount: amountInt64,
}
var params rpctypes.Query4Jrpc
params.Execer = pty.PrivacyX
......
......@@ -44,11 +44,8 @@ func (p *privacy) Exec_Public2Privacy(payload *ty.Public2Privacy, tx *types.Tran
receipt.KV = append(receipt.KV, &types.KeyValue{Key: key, Value: value})
}
receiptPrivacyOutput := &ty.ReceiptPrivacyOutput{
Token: payload.Tokenname,
Keyoutput: payload.GetOutput().Keyoutput,
}
execlog := &types.ReceiptLog{Ty: ty.TyLogPrivacyOutput, Log: types.Encode(receiptPrivacyOutput)}
receiptLogs := p.buildPrivacyReceiptLog(payload.GetAssetExec(), payload.GetTokenname(), payload.GetOutput().GetKeyoutput())
execlog := &types.ReceiptLog{Ty: ty.TyLogPrivacyOutput, Log: types.Encode(receiptLogs)}
receipt.Logs = append(receipt.Logs, execlog)
//////////////////debug code begin///////////////
......@@ -82,12 +79,8 @@ func (p *privacy) Exec_Privacy2Privacy(payload *ty.Privacy2Privacy, tx *types.Tr
value := types.Encode(keyOutput)
receipt.KV = append(receipt.KV, &types.KeyValue{Key: key, Value: value})
}
receiptPrivacyOutput := &ty.ReceiptPrivacyOutput{
Token: payload.Tokenname,
Keyoutput: payload.GetOutput().Keyoutput,
}
execlog = &types.ReceiptLog{Ty: ty.TyLogPrivacyOutput, Log: types.Encode(receiptPrivacyOutput)}
receiptLogs := p.buildPrivacyReceiptLog(payload.GetAssetExec(), payload.GetTokenname(), payload.GetOutput().GetKeyoutput())
execlog = &types.ReceiptLog{Ty: ty.TyLogPrivacyOutput, Log: types.Encode(receiptLogs)}
receipt.Logs = append(receipt.Logs, execlog)
receipt.Ty = types.ExecOk
......@@ -132,11 +125,8 @@ func (p *privacy) Exec_Privacy2Public(payload *ty.Privacy2Public, tx *types.Tran
receipt.KV = append(receipt.KV, &types.KeyValue{Key: key, Value: value})
}
receiptPrivacyOutput := &ty.ReceiptPrivacyOutput{
Token: payload.Tokenname,
Keyoutput: payload.GetOutput().Keyoutput,
}
execlog = &types.ReceiptLog{Ty: ty.TyLogPrivacyOutput, Log: types.Encode(receiptPrivacyOutput)}
receiptLog := p.buildPrivacyReceiptLog(payload.GetAssetExec(), payload.GetTokenname(), payload.GetOutput().GetKeyoutput())
execlog = &types.ReceiptLog{Ty: ty.TyLogPrivacyOutput, Log: types.Encode(receiptLog)}
receipt.Logs = append(receipt.Logs, execlog)
receipt.Ty = types.ExecOk
......@@ -155,3 +145,16 @@ func (p *privacy) createAccountDB(exec, symbol string) (*account.DB, error) {
cfg := p.GetAPI().GetConfig()
return account.NewAccountDB(cfg, exec, symbol, p.GetStateDB())
}
func (p *privacy) buildPrivacyReceiptLog(assetExec, assetSymbol string, output []*ty.KeyOutput) *ty.ReceiptPrivacyOutput {
if assetExec == "" {
assetExec = "coins"
}
receipt := &ty.ReceiptPrivacyOutput{
AssetExec: assetExec,
AssetSymbol: assetSymbol,
Keyoutput: output,
}
return receipt
}
......@@ -26,19 +26,19 @@ func (p *privacy) execDelLocal(tx *types.Transaction, receiptData *types.Receipt
privacylog.Error("PrivacyTrading ExecDelLocal", "txhash", txhashstr, "Decode item.Log error ", err)
panic(err)
}
token := receiptPrivacyOutput.Token
assetExec := receiptPrivacyOutput.GetAssetExec()
assetSymbol := receiptPrivacyOutput.GetAssetSymbol()
txhashInByte := tx.Hash()
txhash := common.ToHex(txhashInByte)
for m, keyOutput := range receiptPrivacyOutput.Keyoutput {
//kv1,添加一个具体的UTXO,方便我们可以查询相应token下特定额度下,不同高度时,不同txhash的UTXO
key := CalcPrivacyUTXOkeyHeight(token, keyOutput.Amount, p.GetHeight(), txhash, i, m)
key := CalcPrivacyUTXOkeyHeight(assetExec, assetSymbol, keyOutput.Amount, p.GetHeight(), txhash, i, m)
kv := &types.KeyValue{Key: key, Value: nil}
dbSet.KV = append(dbSet.KV, kv)
//kv2,添加各种不同额度的kv记录,能让我们很方便的获知本系统存在的所有不同的额度的UTXO
var amountTypes ty.AmountsOfUTXO
key2 := CalcprivacyKeyTokenAmountType(token)
key2 := CalcprivacyKeyTokenAmountType(assetExec, assetSymbol)
value2, err := localDB.Get(key2)
//如果该种token不是第一次进行隐私操作
if err == nil && value2 != nil {
......@@ -63,15 +63,16 @@ func (p *privacy) execDelLocal(tx *types.Transaction, receiptData *types.Receipt
}
//kv3,添加存在隐私交易token的类型
assetKey := calcExecLocalAssetKey(assetExec, assetSymbol)
var tokenNames ty.TokenNamesOfUTXO
key3 := CalcprivacyKeyTokenTypes()
value3, err := localDB.Get(key3)
if err == nil && value3 != nil {
err := types.Decode(value3, &tokenNames)
if err == nil {
if settxhash, ok := tokenNames.TokensMap[token]; ok {
if settxhash, ok := tokenNames.TokensMap[assetKey]; ok {
if settxhash == txhash {
delete(tokenNames.TokensMap, token)
delete(tokenNames.TokensMap, assetKey)
value3 := types.Encode(&tokenNames)
kv := &types.KeyValue{Key: key3, Value: value3}
dbSet.KV = append(dbSet.KV, kv)
......
......@@ -27,12 +27,13 @@ func (p *privacy) execLocal(receiptData *types.ReceiptData, tx *types.Transactio
panic(err) //数据错误了,已经被修改了
}
token := receiptPrivacyOutput.Token
assetExec := receiptPrivacyOutput.GetAssetExec()
assetSymbol := receiptPrivacyOutput.GetAssetSymbol()
txhashInByte := tx.Hash()
txhash := common.ToHex(txhashInByte)
for outputIndex, keyOutput := range receiptPrivacyOutput.Keyoutput {
//kv1,添加一个具体的UTXO,方便我们可以查询相应token下特定额度下,不同高度时,不同txhash的UTXO
key := CalcPrivacyUTXOkeyHeight(token, keyOutput.Amount, p.GetHeight(), txhash, index, outputIndex)
key := CalcPrivacyUTXOkeyHeight(assetExec, assetSymbol, keyOutput.Amount, p.GetHeight(), txhash, index, outputIndex)
localUTXOItem := &ty.LocalUTXOItem{
Height: p.GetHeight(),
Txindex: int32(index),
......@@ -46,7 +47,7 @@ func (p *privacy) execLocal(receiptData *types.ReceiptData, tx *types.Transactio
//kv2,添加各种不同额度的kv记录,能让我们很方便的获知本系统存在的所有不同的额度的UTXO
var amountTypes ty.AmountsOfUTXO
key2 := CalcprivacyKeyTokenAmountType(token)
key2 := CalcprivacyKeyTokenAmountType(assetExec, assetSymbol)
value2, err := localDB.Get(key2)
//如果该种token不是第一次进行隐私操作
if err == nil && value2 != nil {
......@@ -78,14 +79,15 @@ func (p *privacy) execLocal(receiptData *types.ReceiptData, tx *types.Transactio
}
//kv3,添加存在隐私交易token的类型
assetKey := calcExecLocalAssetKey(assetExec, assetSymbol)
var tokenNames ty.TokenNamesOfUTXO
key3 := CalcprivacyKeyTokenTypes()
value3, err := localDB.Get(key3)
if err == nil && len(value3) != 0 {
err := types.Decode(value3, &tokenNames)
if err == nil {
if _, ok := tokenNames.TokensMap[token]; !ok {
tokenNames.TokensMap[token] = txhash
if _, ok := tokenNames.TokensMap[assetKey]; !ok {
tokenNames.TokensMap[assetKey] = txhash
kv := &types.KeyValue{Key: key3, Value: types.Encode(&tokenNames)}
dbSet.KV = append(dbSet.KV, kv)
localDB.Set(key3, types.Encode(&tokenNames))
......@@ -93,7 +95,7 @@ func (p *privacy) execLocal(receiptData *types.ReceiptData, tx *types.Transactio
}
} else {
tokenNames.TokensMap = make(map[string]string)
tokenNames.TokensMap[token] = txhash
tokenNames.TokensMap[assetKey] = txhash
kv := &types.KeyValue{Key: key3, Value: types.Encode(&tokenNames)}
dbSet.KV = append(dbSet.KV, kv)
localDB.Set(key3, types.Encode(&tokenNames))
......
......@@ -40,21 +40,25 @@ func calcPrivacyKeyImageKey(exec, token string, keyimage []byte) []byte {
}
//CalcPrivacyUTXOkeyHeight 在本地数据库中设置一条可以找到对应amount的对应的utxo的global index
func CalcPrivacyUTXOkeyHeight(token string, amount, height int64, txhash string, txindex, outindex int) (key []byte) {
return []byte(fmt.Sprintf(privacyUTXOKEYPrefix+"-%s-%d-%d-%s-%d-%d", token, amount, height, txhash, txindex, outindex))
func CalcPrivacyUTXOkeyHeight(exec, token string, amount, height int64, txhash string, txindex, outindex int) (key []byte) {
return []byte(fmt.Sprintf(privacyUTXOKEYPrefix+"-%s-%s-%d-%d-%s-%d-%d", exec, token, amount, height, txhash, txindex, outindex))
}
// CalcPrivacyUTXOkeyHeightPrefix get privacy utxo key by height and prefix
func CalcPrivacyUTXOkeyHeightPrefix(token string, amount int64) (key []byte) {
return []byte(fmt.Sprintf(privacyUTXOKEYPrefix+"-%s-%d-", token, amount))
func CalcPrivacyUTXOkeyHeightPrefix(exec, token string, amount int64) (key []byte) {
return []byte(fmt.Sprintf(privacyUTXOKEYPrefix+"-%s-%s-%d-", exec, token, amount))
}
//CalcprivacyKeyTokenAmountType 设置当前系统存在的token的amount的类型,如存在1,3,5,100...等等的类型,
func CalcprivacyKeyTokenAmountType(token string) (key []byte) {
return []byte(fmt.Sprintf(privacyAmountTypePrefix+"-%s-", token))
func CalcprivacyKeyTokenAmountType(exec, token string) (key []byte) {
return []byte(fmt.Sprintf(privacyAmountTypePrefix+"-%s-%s-", exec, token))
}
// CalcprivacyKeyTokenTypes get privacy token types key
func CalcprivacyKeyTokenTypes() (key []byte) {
return []byte(privacyTokenTypesPrefix)
}
func calcExecLocalAssetKey(exec, symbol string) string {
return exec + "-" + symbol
}
......@@ -72,10 +72,10 @@ func (p *privacy) GetDriverName() string {
return driverName
}
func (p *privacy) getUtxosByTokenAndAmount(tokenName string, amount int64, count int32) ([]*pty.LocalUTXOItem, error) {
func (p *privacy) getUtxosByTokenAndAmount(exec, tokenName string, amount int64, count int32) ([]*pty.LocalUTXOItem, error) {
localDB := p.GetLocalDB()
var utxos []*pty.LocalUTXOItem
prefix := CalcPrivacyUTXOkeyHeightPrefix(tokenName, amount)
prefix := CalcPrivacyUTXOkeyHeightPrefix(exec, tokenName, amount)
values, err := localDB.List(prefix, nil, count, 0)
if err != nil {
return utxos, err
......@@ -97,13 +97,12 @@ func (p *privacy) getUtxosByTokenAndAmount(tokenName string, amount int64, count
return utxos, nil
}
func (p *privacy) getGlobalUtxoIndex(getUtxoIndexReq *pty.ReqUTXOGlobalIndex) (types.Message, error) {
func (p *privacy) getGlobalUtxoIndex(req *pty.ReqUTXOGlobalIndex) (types.Message, error) {
debugBeginTime := time.Now()
utxoGlobalIndexResp := &pty.ResUTXOGlobalIndex{}
tokenName := getUtxoIndexReq.Tokenname
currentHeight := p.GetHeight()
for _, amount := range getUtxoIndexReq.Amount {
utxos, err := p.getUtxosByTokenAndAmount(tokenName, amount, pty.UTXOCacheCount)
for _, amount := range req.GetAmount() {
utxos, err := p.getUtxosByTokenAndAmount(req.GetAssetExec(), req.GetAssetSymbol(), amount, pty.UTXOCacheCount)
if err != nil {
return utxoGlobalIndexResp, err
}
......@@ -115,7 +114,7 @@ func (p *privacy) getGlobalUtxoIndex(getUtxoIndexReq *pty.ReqUTXOGlobalIndex) (t
}
}
mixCount := getUtxoIndexReq.MixCount
mixCount := req.GetMixCount()
totalCnt := int32(index + 1)
if mixCount > totalCnt {
mixCount = totalCnt
......@@ -154,7 +153,7 @@ func (p *privacy) getGlobalUtxoIndex(getUtxoIndexReq *pty.ReqUTXOGlobalIndex) (t
func (p *privacy) ShowAmountsOfUTXO(reqtoken *pty.ReqPrivacyToken) (types.Message, error) {
querydb := p.GetLocalDB()
key := CalcprivacyKeyTokenAmountType(reqtoken.Token)
key := CalcprivacyKeyTokenAmountType(reqtoken.GetAssetExec(), reqtoken.GetAssetSymbol())
replyAmounts := &pty.ReplyPrivacyAmounts{}
value, err := querydb.Get(key)
if err != nil {
......@@ -182,7 +181,7 @@ func (p *privacy) ShowUTXOs4SpecifiedAmount(reqtoken *pty.ReqPrivacyToken) (type
querydb := p.GetLocalDB()
var replyUTXOsOfAmount pty.ReplyUTXOsOfAmount
values, err := querydb.List(CalcPrivacyUTXOkeyHeightPrefix(reqtoken.Token, reqtoken.Amount), nil, 0, 0)
values, err := querydb.List(CalcPrivacyUTXOkeyHeightPrefix(reqtoken.GetAssetExec(), reqtoken.GetAssetSymbol(), reqtoken.Amount), nil, 0, 0)
if err != nil {
return &replyUTXOsOfAmount, err
}
......
......@@ -61,14 +61,14 @@ func TestPrivacy_Query_ShowAmountsOfUTXO(t *testing.T) {
{
index: 1,
params: &pty.ReqPrivacyToken{
Token: "btc",
AssetSymbol: "btc",
},
expectErr: types.ErrNotFound,
},
{
index: 2,
params: &pty.ReqPrivacyToken{
Token: "bty",
AssetSymbol: "bty",
},
expectReply: &pty.ReplyPrivacyAmounts{
AmountDetail: []*pty.AmountDetail{
......@@ -79,6 +79,8 @@ func TestPrivacy_Query_ShowAmountsOfUTXO(t *testing.T) {
}
for _, tc := range queryCases {
req := tc.params.(*pty.ReqPrivacyToken)
req.AssetExec = "coins"
tc.funcName = "ShowAmountsOfUTXO"
}
testQuery(mock, queryCases, t)
......@@ -99,21 +101,23 @@ func TestPrivacy_Query_ShowUTXOs4SpecifiedAmount(t *testing.T) {
{
index: 1,
params: &pty.ReqPrivacyToken{
Token: "bty",
AssetSymbol: "bty",
},
expectErr: types.ErrNotFound,
},
{
index: 2,
params: &pty.ReqPrivacyToken{
Token: "bty",
Amount: types.Coin,
AssetSymbol: "bty",
Amount: types.Coin,
},
disableReplyCheck: true,
},
}
for _, tc := range queryCases {
req := tc.params.(*pty.ReqPrivacyToken)
req.AssetExec = "coins"
tc.funcName = "ShowUTXOs4SpecifiedAmount"
}
testQuery(mock, queryCases, t)
......@@ -139,9 +143,9 @@ func TestPrivacy_Query_GetUTXOGlobalIndex(t *testing.T) {
{
index: 2,
params: &pty.ReqUTXOGlobalIndex{
Tokenname: "btc",
MixCount: 1,
Amount: []int64{types.Coin},
AssetSymbol: "btc",
MixCount: 1,
Amount: []int64{types.Coin},
},
disableReplyCheck: true,
expectErr: types.ErrNotFound,
......@@ -149,9 +153,9 @@ func TestPrivacy_Query_GetUTXOGlobalIndex(t *testing.T) {
{
index: 3,
params: &pty.ReqUTXOGlobalIndex{
Tokenname: "bty",
MixCount: 1,
Amount: []int64{types.Coin, types.Coin * 2},
AssetSymbol: "bty",
MixCount: 1,
Amount: []int64{types.Coin, types.Coin * 2},
},
disableReplyCheck: true,
expectErr: types.ErrNotFound,
......@@ -159,15 +163,19 @@ func TestPrivacy_Query_GetUTXOGlobalIndex(t *testing.T) {
{
index: 4,
params: &pty.ReqUTXOGlobalIndex{
Tokenname: "bty",
MixCount: 1,
Amount: []int64{types.Coin},
AssetSymbol: "bty",
MixCount: 1,
Amount: []int64{types.Coin},
},
disableReplyCheck: true,
},
}
for _, tc := range queryCases {
req := tc.params.(*pty.ReqUTXOGlobalIndex)
if req.AssetExec == "" {
req.AssetExec = "coins"
}
tc.funcName = "GetUTXOGlobalIndex"
}
testQuery(mock, queryCases, t)
......
......@@ -108,8 +108,9 @@ message ResUTXOPubKeys {
}
message ReqPrivacyToken {
string token = 1;
int64 amount = 2;
string assetExec = 1;
string assetSymbol = 2;
int64 amount = 3;
}
message AmountDetail {
......@@ -126,8 +127,9 @@ message replyUTXOsOfAmount {
}
message ReceiptPrivacyOutput {
string token = 1;
repeated keyOutput keyoutput = 2;
string assetExec = 1;
string assetSymbol = 2;
repeated keyOutput keyoutput = 3;
}
//各种amount额度的UTXO在链上的数量
message AmountsOfUTXO {
......@@ -245,9 +247,10 @@ message UTXOHaveTxHashs {
}
message ReqUTXOGlobalIndex {
string tokenname = 1;
int32 mixCount = 2;
repeated int64 amount = 3;
string assetExec = 1;
string assetSymbol = 2;
int32 mixCount = 3;
repeated int64 amount = 4;
}
message UTXOBasic {
......@@ -261,8 +264,6 @@ message UTXOIndex4Amount {
}
message ResUTXOGlobalIndex {
string tokenname = 1;
int32 mixCount = 2;
repeated UTXOIndex4Amount utxoIndex4Amount = 3;
}
......@@ -402,9 +403,9 @@ message WalletAccountPrivacy {
message ReqCreatePrivacyTx {
string tokenname = 1;
// 构建交易类型
int32 actionType = 2;
int64 amount = 3;
string note = 4;
int32 actionType = 2;
int64 amount = 3;
string note = 4;
// 普通交易的发送方
string from = 5;
// 普通交易的接收方
......
......@@ -93,7 +93,7 @@ func testShowPrivacyAccountSpend(t *testing.T, jrpc *jsonclient.JSONClient) erro
}
func testShowAmountsOfUTXO(t *testing.T, jrpc *jsonclient.JSONClient) error {
reqPrivacyToken := pty.ReqPrivacyToken{Token: types.BTY}
reqPrivacyToken := pty.ReqPrivacyToken{AssetExec: "coins", AssetSymbol: types.BTY}
var params rpctypes.Query4Jrpc
params.Execer = pty.PrivacyX
params.FuncName = "ShowAmountsOfUTXO"
......@@ -106,8 +106,9 @@ func testShowAmountsOfUTXO(t *testing.T, jrpc *jsonclient.JSONClient) error {
func testShowUTXOs4SpecifiedAmount(t *testing.T, jrpc *jsonclient.JSONClient) error {
reqPrivacyToken := pty.ReqPrivacyToken{
Token: types.BTY,
Amount: 123456,
AssetExec: "coins",
AssetSymbol: types.BTY,
Amount: 123456,
}
var params rpctypes.Query4Jrpc
params.Execer = pty.PrivacyX
......
This diff is collapsed.
......@@ -364,7 +364,7 @@ buildInput 构建隐私交易的输入信息
func (policy *privacyPolicy) buildInput(privacykeyParirs *privacy.Privacy, buildInfo *buildInputInfo) (*privacytypes.PrivacyInput, []*privacytypes.UTXOBasics, []*privacytypes.RealKeyInput, []*txOutputInfo, error) {
operater := policy.getWalletOperate()
//挑选满足额度的utxo
selectedUtxo, err := policy.selectUTXO(buildInfo.tokenname, buildInfo.sender, buildInfo.amount)
selectedUtxo, err := policy.selectUTXO(buildInfo.assetSymbol, buildInfo.sender, buildInfo.amount)
if err != nil {
bizlog.Error("buildInput", "Failed to selectOutput for amount", buildInfo.amount,
"Due to cause", err)
......@@ -375,8 +375,9 @@ func (policy *privacyPolicy) buildInput(privacykeyParirs *privacy.Privacy, build
})
reqGetGlobalIndex := privacytypes.ReqUTXOGlobalIndex{
Tokenname: buildInfo.tokenname,
MixCount: 0,
AssetExec: buildInfo.assetExec,
AssetSymbol: buildInfo.assetSymbol,
MixCount: 0,
}
if buildInfo.mixcount > 0 {
......@@ -562,10 +563,11 @@ func (policy *privacyPolicy) createPrivacy2PrivacyTx(req *privacytypes.ReqCreate
utxoBurnedAmount = privacytypes.PrivacyTxFee
}
buildInfo := &buildInputInfo{
tokenname: req.GetTokenname(),
sender: req.GetFrom(),
amount: req.GetAmount() + utxoBurnedAmount,
mixcount: req.GetMixcount(),
assetExec: req.GetAssetExec(),
assetSymbol: req.GetTokenname(),
sender: req.GetFrom(),
amount: req.GetAmount() + utxoBurnedAmount,
mixcount: req.GetMixcount(),
}
privacyInfo, err := policy.getPrivacykeyPair(req.GetFrom())
if err != nil {
......@@ -652,10 +654,11 @@ func (policy *privacyPolicy) createPrivacy2PublicTx(req *privacytypes.ReqCreateP
utxoBurnedAmount = privacytypes.PrivacyTxFee
}
buildInfo := &buildInputInfo{
tokenname: req.GetTokenname(),
sender: req.GetFrom(),
amount: req.GetAmount() + utxoBurnedAmount,
mixcount: req.GetMixcount(),
assetExec: req.GetAssetExec(),
assetSymbol: req.GetTokenname(),
sender: req.GetFrom(),
amount: req.GetAmount() + utxoBurnedAmount,
mixcount: req.GetMixcount(),
}
privacyInfo, err := policy.getPrivacykeyPair(req.GetFrom())
if err != nil {
......
......@@ -16,10 +16,11 @@ type addrAndprivacy struct {
// buildInputInfo 构建隐私交易输入的参数结构
type buildInputInfo struct {
tokenname string
sender string
amount int64
mixcount int32
assetExec string
assetSymbol string
sender string
amount int64
mixcount int32
}
// txOutputInfo 存储当前钱包地址下被选中的UTXO信息
......
......@@ -40,15 +40,14 @@ message PrepareRetrieve {
string defaultAddress = 2;
}
message AssetSymbol {
string exec = 1;
string exec = 1;
string symbol = 2;
}
message PerformRetrieve {
string backupAddress = 1;
string defaultAddress = 2;
string backupAddress = 1;
string defaultAddress = 2;
repeated AssetSymbol assets = 3;
}
......@@ -60,8 +59,8 @@ message CancelRetrieve {
message ReqRetrieveInfo {
string backupAddress = 1;
string defaultAddress = 2;
string assetExec = 3;
string assetSymbol = 4;
string assetExec = 3;
string assetSymbol = 4;
}
message RetrieveQuery {
......
......@@ -3,20 +3,20 @@ package types;
//后面如果有其他数据模型可继续往上面添加
message Storage {
oneof value {
ContentOnlyNotaryStorage contentStorage = 1;
HashOnlyNotaryStorage hashStorage = 2;
LinkNotaryStorage linkStorage = 3;
EncryptNotaryStorage encryptStorage = 4;
ContentOnlyNotaryStorage contentStorage = 1;
HashOnlyNotaryStorage hashStorage = 2;
LinkNotaryStorage linkStorage = 3;
EncryptNotaryStorage encryptStorage = 4;
EncryptShareNotaryStorage encryptShareStorage = 5;
}
}
message StorageAction {
oneof value {
ContentOnlyNotaryStorage contentStorage = 1;
HashOnlyNotaryStorage hashStorage = 2;
LinkNotaryStorage linkStorage = 3;
EncryptNotaryStorage encryptStorage = 4;
ContentOnlyNotaryStorage contentStorage = 1;
HashOnlyNotaryStorage hashStorage = 2;
LinkNotaryStorage linkStorage = 3;
EncryptNotaryStorage encryptStorage = 4;
EncryptShareNotaryStorage encryptShareStorage = 5;
}
int32 ty = 6;
......@@ -24,20 +24,20 @@ message StorageAction {
// 内容存证模型
message ContentOnlyNotaryStorage {
//长度需要小于512k
bytes content = 1;
bytes content = 1;
}
//哈希存证模型,推荐使用sha256哈希,限制256位得摘要值
message HashOnlyNotaryStorage {
//长度固定为32字节
bytes hash = 1;
bytes hash = 1;
}
// 链接存证模型
message LinkNotaryStorage {
//存证内容的链接,可以写入URL,或者其他可用于定位源文件得线索.
bytes link = 1;
bytes link = 1;
//源文件得hash值,推荐使用sha256哈希,限制256位得摘要值
bytes hash = 2;
}
......@@ -45,7 +45,7 @@ message LinkNotaryStorage {
// 隐私存证模型,如果一个文件需要存证,且不公开内容,可以选择将源文件通过对称加密算法加密后上链
message EncryptNotaryStorage {
//存证明文内容的hash值,推荐使用sha256哈希,限制256位得摘要值
bytes contentHash = 1;
bytes contentHash = 1;
//源文件得密文,由加密key及nonce对明文加密得到该值。
bytes encryptContent = 2;
//加密iv,通过AES进行加密时制定随机生成的iv,解密时需要使用该值
......@@ -54,7 +54,7 @@ message EncryptNotaryStorage {
// 隐私存证模型
message EncryptContentOnlyNotaryStorage {
//存证内容的hash值,推荐使用sha256哈希,限制256位得摘要值
// bytes contentHash = 1;
// bytes contentHash = 1;
//源文件得密文。
bytes encryptContent = 1;
//加密iv,通过AES进行加密时制定随机生成的iv,解密时需要使用该值
......@@ -64,7 +64,7 @@ message EncryptContentOnlyNotaryStorage {
// 分享隐私存证模型,需要完备的sdk或者相应的密钥库支持
message EncryptShareNotaryStorage {
//存证明文内容的hash值,推荐使用sha256哈希,限制256位得摘要值
bytes contentHash = 1;
bytes contentHash = 1;
//源文件得密文。
bytes encryptContent = 2;
//密钥的kdf推导路径。密钥tree父节点根据该路径可以推导出私钥key
......@@ -76,9 +76,7 @@ message EncryptShareNotaryStorage {
bytes nonce = 5;
}
service storage {
}
service storage {}
//根据txhash去状态数据库中查询存储内容
message QueryStorage {
string txHash = 1;
......
......@@ -18,7 +18,7 @@ message Ticket {
string minerAddress = 6;
// return wallet
string returnAddress = 7;
//miner Price
// miner Price
int64 price = 9;
}
......@@ -41,9 +41,9 @@ message TicketMiner {
bytes modify = 4;
//挖到区块时公开
bytes privHash = 5;
//VRF计算得到的hash
// VRF计算得到的hash
bytes vrfHash = 6;
//VRF计算得到的proof
// VRF计算得到的proof
bytes vrfProof = 7;
}
......@@ -84,8 +84,8 @@ message TicketGenesis {
}
message TicketClose {
repeated string ticketId = 1;
string minerAddress = 2;
repeated string ticketId = 1;
string minerAddress = 2;
}
message TicketList {
......
......@@ -73,8 +73,8 @@ message ReceiptToken {
}
message ReceiptTokenAmount {
Token prev = 1;
Token current = 2;
Token prev = 1;
Token current = 2;
}
// local
......
......@@ -35,7 +35,7 @@ message TradeForSell {
// 资产来源
string assetExec = 9;
// 定价资产
string priceExec = 10;
string priceExec = 10;
string priceSymbol = 11;
}
......@@ -60,7 +60,7 @@ message TradeForBuyLimit {
int64 totalBoardlot = 5;
string assetExec = 6;
// 定价资产
string priceExec = 7;
string priceExec = 7;
string priceSymbol = 8;
}
......@@ -91,11 +91,11 @@ message SellOrder {
int64 stoptime = 9;
bool crowdfund = 10;
//此处使用tx的hash来指定
string sellID = 11;
int32 status = 12;
int64 height = 13;
string assetExec = 14;
string priceExec = 15;
string sellID = 11;
int32 status = 12;
int64 height = 13;
string assetExec = 14;
string priceExec = 15;
string priceSymbol = 16;
}
......@@ -112,8 +112,8 @@ message BuyLimitOrder {
int32 status = 9;
int64 height = 10;
string assetExec = 11;
string priceExec = 12;
string priceSymbol = 13;
string priceExec = 12;
string priceSymbol = 13;
}
// 执行器日志部分
......@@ -131,8 +131,8 @@ message ReceiptBuyBase {
string txHash = 11;
int64 height = 12;
string assetExec = 13;
string priceExec = 14;
string priceSymbol = 15;
string priceExec = 14;
string priceSymbol = 15;
}
message ReceiptSellBase {
......@@ -153,11 +153,11 @@ message ReceiptSellBase {
string sellID = 11;
string status = 12;
// buyid
string buyID = 13;
string txHash = 14;
int64 height = 15;
string assetExec = 16;
string priceExec = 17;
string buyID = 13;
string txHash = 14;
int64 height = 15;
string assetExec = 16;
string priceExec = 17;
string priceSymbol = 18;
}
......@@ -277,8 +277,8 @@ message ReplyTradeOrder {
int64 blockTime = 14;
bool isSellOrder = 15;
string assetExec = 16;
string priceExec = 17;
string priceSymbol = 18;
string priceExec = 17;
string priceSymbol = 18;
}
message ReplyTradeOrders {
......@@ -301,26 +301,26 @@ message ReqBuyToken {
}
message LocalOrder {
string assetSymbol = 1;
string owner = 2;
int64 amountPerBoardlot = 3;
int64 minBoardlot = 4;
int64 pricePerBoardlot = 5;
int64 totalBoardlot = 6;
int64 tradedBoardlot = 7;
string buyID = 8;
int32 status = 9;
string sellID = 10;
repeated string txHash = 11;
int64 height = 12;
string key = 13;
int64 blockTime = 14;
bool isSellOrder = 15;
string assetExec = 16;
string txIndex = 17;
bool isFinished = 18;
string priceExec = 19;
string priceSymbol = 20;
string assetSymbol = 1;
string owner = 2;
int64 amountPerBoardlot = 3;
int64 minBoardlot = 4;
int64 pricePerBoardlot = 5;
int64 totalBoardlot = 6;
int64 tradedBoardlot = 7;
string buyID = 8;
int32 status = 9;
string sellID = 10;
repeated string txHash = 11;
int64 height = 12;
string key = 13;
int64 blockTime = 14;
bool isSellOrder = 15;
string assetExec = 16;
string txIndex = 17;
bool isFinished = 18;
string priceExec = 19;
string priceSymbol = 20;
}
service trade {
......
......@@ -79,13 +79,13 @@ message UnfreezeTerminate {
// receipt
message ReceiptUnfreeze {
Unfreeze prev = 1;
Unfreeze current = 2;
Unfreeze prev = 1;
Unfreeze current = 2;
}
message LocalUnfreeze {
Unfreeze unfreeze = 1;
string txIndex = 2;
string txIndex = 2;
}
// query
......@@ -95,11 +95,11 @@ message ReplyQueryUnfreezeWithdraw {
}
message ReqUnfreezes {
int32 direction = 1;
int32 count = 2;
string fromKey = 3;
string initiator = 4;
string beneficiary = 5;
int32 direction = 1;
int32 count = 2;
string fromKey = 3;
string initiator = 4;
string beneficiary = 5;
}
message ReplyUnfreeze {
......@@ -124,8 +124,8 @@ message ReplyUnfreeze {
FixAmount fixAmount = 10;
LeftProportion leftProportion = 11;
}
bool terminated = 12;
string key = 13;
bool terminated = 12;
string key = 13;
}
message ReplyUnfreezes {
repeated ReplyUnfreeze unfreeze = 1;
......
......@@ -30,9 +30,9 @@ message TendermintCommit {
}
message TendermintBlockInfo {
State State = 2;
Proposal Proposal = 3;
TendermintBlock block = 4;
State State = 2;
Proposal Proposal = 3;
TendermintBlock block = 4;
}
message BlockSize {
......@@ -87,7 +87,6 @@ message State {
bytes AppHash = 12;
}
message TendermintBlockHeader {
string chainID = 1;
int64 height = 2;
......@@ -105,9 +104,9 @@ message TendermintBlockHeader {
}
message TendermintBlock {
TendermintBlockHeader header = 1;
Block data = 2;
TendermintCommit lastCommit = 4;
TendermintBlockHeader header = 1;
Block data = 2;
TendermintCommit lastCommit = 4;
}
message Proposal {
......@@ -132,7 +131,7 @@ message ValidBlockMsg {
int64 height = 1;
int32 round = 2;
bytes blockhash = 3;
bool isCommit = 4;
bool isCommit = 4;
}
message ProposalPOLMsg {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment