新注册的用户请输入邮箱并保存,随后登录邮箱激活账号。后续可直接使用邮箱登录!

Commit fa8c23d4 authored by shaozhuguang's avatar shaozhuguang

Merge branch 'v2.4.0_qc_dpos_ted' into 'v2.4.0_qc' (merge request !297)

 feat: 修改dpos多个bug  --story=1
parents 8ffcc6ae 94784506
......@@ -242,6 +242,26 @@ func NewDPoSStakeRuntime(log protocol.Logger) *DPoSStakeRuntime {
}
// SetNodeID - 系统加入节点绑定自身身份
// 该函数实现以下安全约束:
// 1. 每个sender只能绑定一个nodeID,重复调用将失败
// 2. 每个nodeID只能被一个sender绑定,防止身份冲突
// 3. 绑定关系一旦建立不可修改,确保身份系统的稳定性
// 4. 使用双向映射(N/{sender} 和 NR/{nodeID})实现高效的关系验证
//
// 参数:
//
// context - 交易上下文,提供账本访问接口
// params - 必须包含paramNodeID参数,携带节点ID信息
//
// 返回值:
//
// []byte - 成功时返回节点ID字节,失败返回具体错误
// error - 错误类型包括:
// - 参数校验失败(缺少参数或空值)
// - 发送者地址解析失败
// - 节点ID已被其他发送者注册
// - 当前发送者已存在绑定记录
// - 账本状态保存失败
func (s *DPoSStakeRuntime) SetNodeID(context protocol.TxSimContext, params map[string][]byte) ([]byte, error) {
// check params
err := checkParams(params, paramNodeID)
......@@ -249,10 +269,13 @@ func (s *DPoSStakeRuntime) SetNodeID(context protocol.TxSimContext, params map[s
return nil, err
}
nodeID := string(params[paramNodeID])
if len(nodeID) <= 0 {
return nil, fmt.Errorf("invalid nodeid")
}
// get message sender
sender, err := loadSenderAddress(context) // Use ERC20 parse method
if err != nil {
s.log.Errorf("get sender address error: ", err.Error())
s.log.Error("get sender address error: ", err.Error())
return nil, err
}
// construct kv pair
......@@ -268,6 +291,13 @@ func (s *DPoSStakeRuntime) SetNodeID(context protocol.TxSimContext, params map[s
s.log.Errorf("the nodeID:[%s] has been set by [%s]", nodeID, val)
return nil, fmt.Errorf("the nodeID:[%s] has been set by [%s]", nodeID, val)
}
if val, err := context.Get(syscontract.SystemContract_DPOS_STAKE.String(), key); err != nil {
s.log.Errorf("query state from context failed, reason: %s", err)
return nil, fmt.Errorf("query state from context failed, reason: %s", err)
} else if len(val) > 0 {
s.log.Errorf("the key:[%s] has set to [%s]", sender, val)
return nil, fmt.Errorf("the key:[%s] has set to [%s]", sender, val)
}
// save to context
if err := context.Put(syscontract.SystemContract_DPOS_STAKE.String(), key, []byte(nodeID)); err != nil {
s.log.Errorf("context put key: [%s], value: [&s] error, error: ", key, nodeID, err)
......@@ -316,7 +346,7 @@ func (s *DPoSStakeRuntime) GetAllCandidates(context protocol.TxSimContext, param
// 序列化
bz, err := proto.Marshal(collection)
if err != nil {
s.log.Errorf("marshal validator collection error: ", err.Error())
s.log.Error("marshal validator collection error: ", err.Error())
return nil, err
}
return bz, nil
......@@ -389,65 +419,65 @@ func (s *DPoSStakeRuntime) Delegate(context protocol.TxSimContext, params map[st
// check amount
if !assertStringAmountOverZero(amount) {
s.log.Errorf("amount is less than or equal to 0")
return nil, fmt.Errorf("amount is less than or equal to 0")
s.log.Errorf("amount must be greater than 0")
return nil, fmt.Errorf("amount must be greater than 0")
}
// 解析交易发送方地址
from, err := loadSenderAddress(context) // Use ERC20 parse method
if err != nil {
s.log.Errorf("get sender address error: ", err.Error())
s.log.Error("get sender address error: ", err.Error())
return nil, err
}
// 查看 validator 是否存在
v, err := getOrCreateValidator(context, from, to)
if err != nil {
s.log.Errorf("get or create validator error: ", err.Error())
s.log.Error("get or create validator error: ", err.Error())
return nil, err
}
// 获取或者创建 Delegation
d, err := getOrCreateDelegation(context, from, to)
if err != nil {
s.log.Errorf("get or create delegation error: ", err.Error())
s.log.Error("get or create delegation error: ", err.Error())
return nil, err
}
// 计算抵押获得的 share
shares, err := calcShareByAmount(v.Tokens, v.DelegatorShares, amount)
if err != nil {
s.log.Errorf("calculate share by amount error: ", err.Error())
s.log.Error("calculate share by amount error: ", err.Error())
return nil, err
}
// 更新 delegation 的 share
err = updateDelegateShares(d, shares)
if err != nil {
s.log.Errorf("update delegate share error", err.Error())
s.log.Error("update delegate share error", err.Error())
return nil, err
}
// 更新 validator
err = updateValidatorShares(v, shares)
if err != nil {
s.log.Errorf("update shares error: ", err.Error())
s.log.Error("update shares error: ", err.Error())
return nil, err
}
err = updateValidatorTokens(v, amount)
if err != nil {
s.log.Errorf("update tokens error: ", err.Error())
s.log.Error("update tokens error: ", err.Error())
return nil, err
}
var cmp int
if from == to {
err = updateValidatorSelfDelegate(v, amount)
if err != nil {
s.log.Errorf("update self delegate error: ", err.Error())
s.log.Error("update self delegate error: ", err.Error())
return nil, err
}
cmp, err = compareMinSelfDelegation(context, v.SelfDelegation)
if err != nil {
s.log.Errorf("compare min self delegation error: ", err.Error())
s.log.Error("compare min self delegation error: ", err.Error())
return nil, err
}
if v.Status != syscontract.BondStatus_BONDED && cmp >= 0 {
......@@ -469,19 +499,19 @@ func (s *DPoSStakeRuntime) Delegate(context protocol.TxSimContext, params map[st
}
_, err = erc20RunTime.Transfer(context, transferParams)
if err != nil {
s.log.Errorf("cross call contract ERC20, method transfer error: ", err.Error())
s.log.Error("cross call contract ERC20, method transfer error: ", err.Error())
return nil, err
}
// 写入存储
err = save(context, ToDelegationKey(from, to), d)
if err != nil {
s.log.Errorf("save delegate error: ", err.Error())
s.log.Error("save delegate error: ", err.Error())
return nil, err
}
err = save(context, ToValidatorKey(to), v)
if err != nil {
s.log.Errorf("save validator error: ", err.Error())
s.log.Error("save validator error: ", err.Error())
return nil, err
}
......@@ -549,32 +579,32 @@ func (s *DPoSStakeRuntime) UnDelegate(context protocol.TxSimContext, params map[
amount := string(params[paramAmount])
// check amount
if !assertStringAmountPositive(amount) {
s.log.Errorf("amount is less than 0")
return nil, fmt.Errorf("amount is less than 0")
if !assertStringAmountOverZero(amount) {
s.log.Errorf("amount must be greater than 0")
return nil, fmt.Errorf("amount must be greater than 0")
}
// read epoch
epoch, err := s.readEpoch(context)
if err != nil {
s.log.Errorf("undelegate unmarshal latest epoch error")
s.log.Error("undelegate unmarshal latest epoch error")
return nil, err
}
// parse sender
sender, err := loadSenderAddress(context) // Use ERC20 parse method
if err != nil {
s.log.Errorf("get sender address error: ", err.Error())
s.log.Error("get sender address error: ", err.Error())
return nil, err
}
// check epoch undelegate amount
shares, err := s.checkEpochUnDelegateAmount(context, sender, undelegateValidatorAddress, amount)
if err != nil {
s.log.Errorf("check epoch undelegate amount error: ", err.Error())
s.log.Error("check epoch undelegate amount error: ", err.Error())
return nil, err
}
// get completion epochID
epochNum, err := getUnbondingEpochNumber(context)
if err != nil {
s.log.Errorf("get completion epoch error: ", err.Error())
s.log.Error("get completion epoch error: ", err.Error())
return nil, err
}
completeEpoch := epochNum + epoch.EpochId
......@@ -583,7 +613,7 @@ func (s *DPoSStakeRuntime) UnDelegate(context protocol.TxSimContext, params map[
// update delegation
ud, err := getOrCreateUnbondingDelegation(context, completeEpoch, sender, undelegateValidatorAddress)
if err != nil {
s.log.Errorf("get or create unbonding delegation error: ", err.Error())
s.log.Error("get or create unbonding delegation error: ", err.Error())
return nil, err
}
ud.Entries = append(ud.Entries, entry)
......@@ -591,30 +621,32 @@ func (s *DPoSStakeRuntime) UnDelegate(context protocol.TxSimContext, params map[
// update validator and delegation
v, d, err := s.updateValidatorAndDelegationByUndelegate(context, sender, undelegateValidatorAddress, amount, shares)
if err != nil {
s.log.Errorf("update validator and delegation error: ", err.Error())
s.log.Error("update validator and delegation error: ", err.Error())
return nil, err
}
// save
err = save(context, ToUnbondingDelegationKey(completeEpoch, sender, undelegateValidatorAddress), ud)
if err != nil {
s.log.Errorf("save unbonding delegation error: ", err.Error())
s.log.Error("save unbonding delegation error: ", err.Error())
return nil, err
}
v.UnbondingEpochId = epoch.EpochId
v.UnbondingCompletionEpochId = completeEpoch
err = save(context, ToValidatorKey(undelegateValidatorAddress), v)
if err != nil {
s.log.Errorf("save validator error: ", err.Error())
s.log.Error("save validator error: ", err.Error())
return nil, err
}
if d.Shares == "0" {
err = del(context, ToDelegationKey(sender, undelegateValidatorAddress))
if err != nil {
s.log.Errorf("delete delegation error: ", err.Error())
s.log.Error("delete delegation error: ", err.Error())
return nil, err
}
} else {
err = save(context, ToDelegationKey(sender, undelegateValidatorAddress), d)
if err != nil {
s.log.Errorf("save delegation error: ", err.Error())
s.log.Error("save delegation error: ", err.Error())
return nil, err
}
}
......@@ -1037,7 +1069,7 @@ func (s *DPoSStakeRuntime) updateValidatorAndDelegationByUndelegate(
// compare self delegation
cmp, err = compareMinSelfDelegation(context, v.SelfDelegation)
if err != nil {
s.log.Errorf("compare min self delegation error: ", err.Error())
s.log.Error("compare min self delegation error: ", err.Error())
return nil, nil, err
}
if cmp == -1 {
......@@ -1057,12 +1089,12 @@ func (s *DPoSStakeRuntime) updateValidatorAndDelegationByUndelegate(
// update delegation
d, err := getDelegation(context, sender, undelegateValidatorAddress)
if err != nil {
s.log.Errorf("get delegation error: ", err.Error())
s.log.Error("get delegation error: ", err.Error())
return nil, nil, err
}
err = updateDelegateShares(d, negShare)
if err != nil {
s.log.Errorf("update delegate shares error: ", err.Error())
s.log.Error("update delegate shares error: ", err.Error())
return nil, nil, err
}
return v, d, nil
......@@ -1324,7 +1356,7 @@ func (s *DPoSStakeRuntime) getERC20ContractOwner(context protocol.TxSimContext)
bz, err := erc20RunTime.Owner(context, nil)
if err != nil {
s.log.Errorf("cross call contract ERC20, method owner error: ", err.Error())
s.log.Error("cross call contract ERC20, method owner error: ", err.Error())
return "", err
}
return string(bz), nil
......@@ -1335,12 +1367,12 @@ func (s *DPoSStakeRuntime) checkSenderAndOwner(context protocol.TxSimContext) er
// get message sender
sender, err := loadSenderAddress(context) // Use ERC20 parse method
if err != nil {
s.log.Errorf("get sender address error: ", err.Error())
s.log.Error("get sender address error: ", err.Error())
return err
}
owner, err := s.getERC20ContractOwner(context)
if err != nil {
s.log.Errorf("get erc20 owner address error: ", err.Error())
s.log.Error("get erc20 owner address error: ", err.Error())
return err
}
if sender != owner {
......
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