diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml
index a910a5c05..79206f845 100644
--- a/.github/workflows/go.yml
+++ b/.github/workflows/go.yml
@@ -7,7 +7,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
- go: ["1.16"]
+ go: ["1.20"]
steps:
- name: Set up Go ${{ matrix.go }}
diff --git a/account/common.go b/account/common.go
index f6b1bb22b..eb18d1e22 100644
--- a/account/common.go
+++ b/account/common.go
@@ -9,8 +9,8 @@ import (
"encoding/hex"
"github.com/elastos/Elastos.ELA/common"
- "github.com/elastos/Elastos.ELA/core/contract"
"github.com/elastos/Elastos.ELA/crypto"
+ "github.com/elastos/Elastos.ELA/dpos/state"
)
const (
@@ -33,7 +33,7 @@ func GetSigners(code []byte) ([]*common.Uint160, error) {
var signers []*common.Uint160
for _, publicKey := range publicKeys {
- hash, err := contract.PublicKeyToStandardCodeHash(publicKey[1:])
+ hash, err := state.GetOwnerKeyCodeHash(publicKey[1:])
if err != nil {
return nil, err
}
@@ -51,7 +51,7 @@ func GetCorssChainSigners(code []byte) ([]*common.Uint160, error) {
var signers []*common.Uint160
for _, publicKey := range publicKeys {
- hash, err := contract.PublicKeyToStandardCodeHash(publicKey[1:])
+ hash, err := state.GetOwnerKeyCodeHash(publicKey[1:])
if err != nil {
return nil, err
}
diff --git a/blockchain/blockchain.go b/blockchain/blockchain.go
index f23e64b15..0dde2b7c8 100644
--- a/blockchain/blockchain.go
+++ b/blockchain/blockchain.go
@@ -302,7 +302,6 @@ func (b *BlockChain) InitCheckpoint(interrupt <-chan struct{},
barStart(bestHeight - startHeight)
}
- var lastBlock Block
for i := startHeight; i <= bestHeight; i++ {
hash, e := b.GetBlockHash(i)
if e != nil {
@@ -315,17 +314,6 @@ func (b *BlockChain) InitCheckpoint(interrupt <-chan struct{},
break
}
- if b.AncestorBlock.Height == 0 && block.Height > b.chainParams.DPoSV2StartHeight {
- // tod check block
- err := b.CheckTransactions(block.Block)
- if err != nil {
- b.AncestorBlock = lastBlock
- log.Info("transaction check error:", err)
- } else {
- lastBlock = *block.Block
- }
- }
-
if block.Height >= b.chainParams.DPoSV2StartHeight {
CalculateTxsFee(block.Block)
} else {
@@ -349,20 +337,6 @@ func (b *BlockChain) InitCheckpoint(interrupt <-chan struct{},
}
}
- //log.Info("ancestor block height:", b.AncestorBlock.Height)
- //if b.AncestorBlock.Height != 0 {
- // log.Info("ReorganizeChain2 ancestor block height:", b.AncestorBlock.Height)
- // err := b.ReorganizeChain2(&b.AncestorBlock)
- // if err != nil {
- // log.Info("ReorganizeChain2 error:", err)
- // panic(err)
- // }
- //
- // b.db.Close()
- // log.Info("###################### need to restart again ######################")
- // os.Exit(0)
- //}
-
done <- struct{}{}
}()
select {
diff --git a/blockchain/blockvalidator.go b/blockchain/blockvalidator.go
index 4e8dafe2b..98ec2ce37 100644
--- a/blockchain/blockvalidator.go
+++ b/blockchain/blockvalidator.go
@@ -166,7 +166,7 @@ func CheckDuplicateTx(block *Block) error {
return errors.New("[PowCheckBlockSanity] invalid register producer payload")
}
- producer := BytesToHexString(producerPayload.OwnerPublicKey)
+ producer := BytesToHexString(producerPayload.OwnerKey)
// Check for duplicate producer in a block
if _, exists := existingProducer[producer]; exists {
return errors.New("[PowCheckBlockSanity] block contains duplicate producer")
@@ -185,7 +185,7 @@ func CheckDuplicateTx(block *Block) error {
return errors.New("[PowCheckBlockSanity] invalid update producer payload")
}
- producer := BytesToHexString(producerPayload.OwnerPublicKey)
+ producer := BytesToHexString(producerPayload.OwnerKey)
// Check for duplicate producer in a block
if _, exists := existingProducer[producer]; exists {
return errors.New("[PowCheckBlockSanity] block contains duplicate producer")
@@ -204,7 +204,7 @@ func CheckDuplicateTx(block *Block) error {
return errors.New("[PowCheckBlockSanity] invalid cancel producer payload")
}
- producer := BytesToHexString(processProducerPayload.OwnerPublicKey)
+ producer := BytesToHexString(processProducerPayload.OwnerKey)
// Check for duplicate producer in a block
if _, exists := existingProducer[producer]; exists {
return errors.New("[PowCheckBlockSanity] block contains duplicate producer")
@@ -339,7 +339,20 @@ func (b *BlockChain) CheckBlockContext(block *Block, prevNode *BlockNode) error
if block.Height >= b.chainParams.DPoSConfiguration.RecordSponsorStartHeight {
lastBlock, err := b.GetDposBlockByHash(*prevNode.Hash)
if err != nil {
- return errors.New("get last block failed")
+ // try get block from cache
+ lastBlockInCache, ok := b.blockCache[*prevNode.Hash]
+ if !ok {
+ return errors.New("get last block failed")
+ }
+ lastConfirmInCache, ok := b.confirmCache[*prevNode.Hash]
+ if !ok {
+ return errors.New("get last block confirm failed")
+ }
+ lastBlock = &DposBlock{
+ Block: lastBlockInCache,
+ HaveConfirm: lastConfirmInCache != nil,
+ Confirm: lastConfirmInCache,
+ }
}
if lastBlock.Confirm == nil && recordSponsorExist {
diff --git a/blockchain/indexers/checkpoint.go b/blockchain/indexers/checkpoint.go
index 28a3037ae..2265843b2 100644
--- a/blockchain/indexers/checkpoint.go
+++ b/blockchain/indexers/checkpoint.go
@@ -95,6 +95,10 @@ func (c *Checkpoint) OnInit() {
}
+func (c *Checkpoint) SaveStartHeight() uint32 {
+ return 500000
+}
+
func (c *Checkpoint) StartHeight() uint32 {
//return math.MaxInt32
return 500000
diff --git a/blockchain/validation.go b/blockchain/validation.go
index 8d7dc7b8d..2a993af6b 100644
--- a/blockchain/validation.go
+++ b/blockchain/validation.go
@@ -6,12 +6,12 @@
package blockchain
import (
- "crypto/sha256"
"errors"
"sort"
"github.com/elastos/Elastos.ELA/common"
+ "github.com/elastos/Elastos.ELA/common/log"
"github.com/elastos/Elastos.ELA/core/contract"
. "github.com/elastos/Elastos.ELA/core/contract/program"
common2 "github.com/elastos/Elastos.ELA/core/types/common"
@@ -48,19 +48,23 @@ func RunPrograms(data []byte, programHashes []common.Uint168, programs []*Progra
if !ownerHash.IsEqual(*codeHash) {
return errors.New("the data hashes is different with corresponding program code")
}
-
if prefixType == contract.PrefixStandard || prefixType == contract.PrefixDeposit {
if contract.IsSchnorr(program.Code) {
if ok, err := checkSchnorrSignatures(*program, common.Sha256D(data[:])); !ok {
return errors.New("check schnorr signature failed:" + err.Error())
}
- } else {
+ } else if contract.IsStandard(program.Code) {
if err := CheckStandardSignature(*program, data); err != nil {
return err
}
+ } else if contract.IsMultiSig(program.Code) {
+ log.Info("mulitisign deposite")
+ if err := crypto.CheckMultiSigSignatures(*program, data); err != nil {
+ return err
+ }
}
} else if prefixType == contract.PrefixMultiSig {
- if err := CheckMultiSigSignatures(*program, data); err != nil {
+ if err := crypto.CheckMultiSigSignatures(*program, data); err != nil {
return err
}
} else {
@@ -116,23 +120,6 @@ func CheckStandardSignature(program Program, data []byte) error {
return crypto.Verify(*publicKey, data, program.Parameter[1:])
}
-func CheckMultiSigSignatures(program Program, data []byte) error {
- code := program.Code
- // Get N parameter
- n := int(code[len(code)-2]) - crypto.PUSH1 + 1
- // Get M parameter
- m := int(code[0]) - crypto.PUSH1 + 1
- if m < 1 || m > n {
- return errors.New("invalid multi sign script code")
- }
- publicKeys, err := crypto.ParseMultisigScript(code)
- if err != nil {
- return err
- }
-
- return verifyMultisigSignatures(m, n, publicKeys, program.Parameter, data)
-}
-
func checkSchnorrSignatures(program Program, data [32]byte) (bool, error) {
publicKey := [33]byte{}
copy(publicKey[:], program.Code[2:])
@@ -154,50 +141,7 @@ func checkCrossChainSignatures(program Program, data []byte) error {
return err
}
- return verifyMultisigSignatures(m, n, publicKeys, program.Parameter, data)
-}
-
-func verifyMultisigSignatures(m, n int, publicKeys [][]byte, signatures, data []byte) error {
- if len(publicKeys) != n {
- return errors.New("invalid multi sign public key script count")
- }
- if len(signatures)%crypto.SignatureScriptLength != 0 {
- return errors.New("invalid multi sign signatures, length not match")
- }
- if len(signatures)/crypto.SignatureScriptLength < m {
- return errors.New("invalid signatures, not enough signatures")
- }
- if len(signatures)/crypto.SignatureScriptLength > n {
- return errors.New("invalid signatures, too many signatures")
- }
-
- var verified = make(map[common.Uint256]struct{})
- for i := 0; i < len(signatures); i += crypto.SignatureScriptLength {
- // Remove length byte
- sign := signatures[i : i+crypto.SignatureScriptLength][1:]
- // Match public key with signature
- for _, publicKey := range publicKeys {
- pubKey, err := crypto.DecodePoint(publicKey[1:])
- if err != nil {
- return err
- }
- err = crypto.Verify(*pubKey, data, sign)
- if err == nil {
- hash := sha256.Sum256(publicKey)
- if _, ok := verified[hash]; ok {
- return errors.New("duplicated signatures")
- }
- verified[hash] = struct{}{}
- break // back to public keys loop
- }
- }
- }
- // Check signatures count
- if len(verified) < m {
- return errors.New("matched signatures not enough")
- }
-
- return nil
+ return crypto.VerifyMultisigSignatures(m, n, publicKeys, program.Parameter, data)
}
func SortPrograms(programs []*Program) {
diff --git a/cmd/script/api/dposmanager.go b/cmd/script/api/dposmanager.go
index a23ea405e..1e378aa74 100644
--- a/cmd/script/api/dposmanager.go
+++ b/cmd/script/api/dposmanager.go
@@ -8,6 +8,7 @@ package api
import (
"encoding/json"
"fmt"
+ "math"
"strconv"
"time"
@@ -88,7 +89,7 @@ func newDposManager(L *lua.LState) int {
TimeSource: medianTime,
})
- mockManager.Consensus = NewConsensus(dposManager, 5*time.Second, mockManager.Handler)
+ mockManager.Consensus = NewConsensus(dposManager, 5*time.Second, mockManager.Handler, math.MaxUint32)
mockManager.Dispatcher, mockManager.IllegalMonitor = NewDispatcherAndIllegalMonitor(ProposalDispatcherConfig{
EventMonitor: mockManager.EventMonitor,
Consensus: mockManager.Consensus,
@@ -324,7 +325,7 @@ func dposManagerSignVote(L *lua.LState) int {
return 1
}
-//mock object of dpos manager
+// mock object of dpos manager
type manager struct {
*DPOSManager
Account account.Account
diff --git a/cmd/script/api/payloadtype.go b/cmd/script/api/payloadtype.go
index 518956e8f..37cf1c1ba 100644
--- a/cmd/script/api/payloadtype.go
+++ b/cmd/script/api/payloadtype.go
@@ -19,6 +19,7 @@ import (
"github.com/elastos/Elastos.ELA/core/types/outputpayload"
"github.com/elastos/Elastos.ELA/core/types/payload"
"github.com/elastos/Elastos.ELA/crypto"
+ "github.com/elastos/Elastos.ELA/dpos/state"
lua "github.com/yuin/gopher-lua"
)
@@ -595,7 +596,7 @@ func RegisterUpdateProducerType(L *lua.LState) {
L.SetField(mt, "__index", L.SetFuncs(L.NewTable(), updateProducerMethods))
}
-//luaUpdateV2ProducerName
+// luaUpdateV2ProducerName
func RegisterUpdateV2ProducerType(L *lua.LState) {
mt := L.NewTypeMetatable(luaUpdateV2ProducerName)
L.SetGlobal("updatev2producer", mt)
@@ -607,7 +608,7 @@ func RegisterUpdateV2ProducerType(L *lua.LState) {
// Constructor
func newUpdateV2Producer(L *lua.LState) int {
- ownerPublicKeyStr := L.ToString(1)
+ ownerKeyStr := L.ToString(1)
nodePublicKeyStr := L.ToString(2)
nickName := L.ToString(3)
url := L.ToString(4)
@@ -624,7 +625,7 @@ func newUpdateV2Producer(L *lua.LState) int {
}
}
- ownerPublicKey, err := common.HexStringToBytes(ownerPublicKeyStr)
+ ownerKey, err := common.HexStringToBytes(ownerKeyStr)
if err != nil {
fmt.Println("wrong producer public key")
os.Exit(1)
@@ -635,13 +636,13 @@ func newUpdateV2Producer(L *lua.LState) int {
os.Exit(1)
}
updateProducer := &payload.ProducerInfo{
- OwnerPublicKey: []byte(ownerPublicKey),
- NodePublicKey: []byte(nodePublicKey),
- NickName: nickName,
- Url: url,
- Location: uint64(location),
- NetAddress: address,
- StakeUntil: uint32(stakeuntil),
+ OwnerKey: []byte(ownerKey),
+ NodePublicKey: []byte(nodePublicKey),
+ NickName: nickName,
+ Url: url,
+ Location: uint64(location),
+ NetAddress: address,
+ StakeUntil: uint32(stakeuntil),
}
if needSign {
@@ -651,7 +652,7 @@ func newUpdateV2Producer(L *lua.LState) int {
version = payload.ProducerInfoDposV2Version
}
- codeHash, err := contract.PublicKeyToStandardCodeHash(ownerPublicKey)
+ codeHash, err := state.GetOwnerKeyCodeHash(ownerKey)
if err != nil {
fmt.Println(err)
os.Exit(1)
@@ -694,20 +695,21 @@ func newUpdateV2Producer(L *lua.LState) int {
// Constructor
func newUpdateProducer(L *lua.LState) int {
- ownerPublicKeyStr := L.ToString(1)
+ ownerKeyStr := L.ToString(1)
nodePublicKeyStr := L.ToString(2)
nickName := L.ToString(3)
url := L.ToString(4)
location := L.ToInt64(5)
address := L.ToString(6)
stakeuntil := L.ToInt64(7)
+ payloadversion := L.ToInt(8)
needSign := true
- client, err := checkClient(L, 8)
+ client, err := checkClient(L, 9)
if err != nil {
needSign = false
}
- ownerPublicKey, err := common.HexStringToBytes(ownerPublicKeyStr)
+ ownerKey, err := common.HexStringToBytes(ownerKeyStr)
if err != nil {
fmt.Println("wrong producer public key")
os.Exit(1)
@@ -718,28 +720,29 @@ func newUpdateProducer(L *lua.LState) int {
os.Exit(1)
}
updateProducer := &payload.ProducerInfo{
- OwnerPublicKey: []byte(ownerPublicKey),
- NodePublicKey: []byte(nodePublicKey),
- NickName: nickName,
- Url: url,
- Location: uint64(location),
- NetAddress: address,
- StakeUntil: uint32(stakeuntil),
+ OwnerKey: []byte(ownerKey),
+ NodePublicKey: []byte(nodePublicKey),
+ NickName: nickName,
+ Url: url,
+ Location: uint64(location),
+ NetAddress: address,
+ StakeUntil: uint32(stakeuntil),
}
- if needSign {
+ if needSign && payloadversion != int(payload.ProducerInfoMultiVersion) {
upSignBuf := new(bytes.Buffer)
version := payload.ProducerInfoVersion
if stakeuntil != 0 {
version = payload.ProducerInfoDposV2Version
}
+ version = byte(payloadversion)
err = updateProducer.SerializeUnsigned(upSignBuf, version)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
- codeHash, err := contract.PublicKeyToStandardCodeHash(ownerPublicKey)
+ codeHash, err := state.GetOwnerKeyCodeHash(ownerKey)
acc := client.GetAccountByCodeHash(*codeHash)
if acc == nil {
fmt.Println("no available account in wallet")
@@ -840,12 +843,12 @@ func newRegisterProducer(L *lua.LState) int {
}
registerProducer := &payload.ProducerInfo{
- OwnerPublicKey: []byte(ownerPublicKey),
- NodePublicKey: []byte(nodePublicKey),
- NickName: nickName,
- Url: url,
- Location: uint64(location),
- NetAddress: address,
+ OwnerKey: []byte(ownerPublicKey),
+ NodePublicKey: []byte(nodePublicKey),
+ NickName: nickName,
+ Url: url,
+ Location: uint64(location),
+ NetAddress: address,
}
if needSign {
@@ -855,7 +858,7 @@ func newRegisterProducer(L *lua.LState) int {
fmt.Println(err)
os.Exit(1)
}
- codeHash, err := contract.PublicKeyToStandardCodeHash(ownerPublicKey)
+ codeHash, err := state.GetOwnerKeyCodeHash(ownerPublicKey)
acc := client.GetAccountByCodeHash(*codeHash)
if acc == nil {
fmt.Println("no available account in wallet")
@@ -879,17 +882,21 @@ func newRegisterProducer(L *lua.LState) int {
// Constructor
func newRegisterV2Producer(L *lua.LState) int {
- ownerPublicKeyStr := L.ToString(1)
+ ownerKeyStr := L.ToString(1)
nodePublicKeyStr := L.ToString(2)
nickName := L.ToString(3)
url := L.ToString(4)
location := L.ToInt64(5)
address := L.ToString(6)
stakeUntil := L.ToInt64(7)
+ payloadversion := L.ToInt(8)
+
fmt.Println(" newRegisterV2Producer stakeUntil", stakeUntil)
+ fmt.Println(" newRegisterV2Producer payloadversion", payloadversion)
+
needSign := true
var account *account.SchnorAccount
- client, err := checkClient(L, 8)
+ client, err := checkClient(L, 9)
if err != nil {
account, err = checkAccount(L, 9)
if err != nil {
@@ -897,7 +904,7 @@ func newRegisterV2Producer(L *lua.LState) int {
}
}
- ownerPublicKey, err := common.HexStringToBytes(ownerPublicKeyStr)
+ ownerKey, err := common.HexStringToBytes(ownerKeyStr)
if err != nil {
fmt.Println("wrong producer public key")
os.Exit(1)
@@ -909,25 +916,25 @@ func newRegisterV2Producer(L *lua.LState) int {
}
registerProducer := &payload.ProducerInfo{
- OwnerPublicKey: []byte(ownerPublicKey),
- NodePublicKey: []byte(nodePublicKey),
- NickName: nickName,
- Url: url,
- Location: uint64(location),
- NetAddress: address,
- StakeUntil: uint32(stakeUntil),
+ OwnerKey: []byte(ownerKey),
+ NodePublicKey: []byte(nodePublicKey),
+ NickName: nickName,
+ Url: url,
+ Location: uint64(location),
+ NetAddress: address,
+ StakeUntil: uint32(stakeUntil),
}
- if needSign {
+ if needSign && payloadversion != int(payload.ProducerInfoMultiVersion) {
rpSignBuf := new(bytes.Buffer)
- codeHash, err := contract.PublicKeyToStandardCodeHash(ownerPublicKey)
+ codeHash, err := state.GetOwnerKeyCodeHash(ownerKey)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
if account == nil {
- err = registerProducer.SerializeUnsigned(rpSignBuf, payload.ProducerInfoDposV2Version)
+ err = registerProducer.SerializeUnsigned(rpSignBuf, byte(payloadversion))
if err != nil {
fmt.Println(err)
os.Exit(1)
@@ -945,7 +952,7 @@ func newRegisterV2Producer(L *lua.LState) int {
registerProducer.Signature = rpSig
} else {
fmt.Println("process AggregateSignatures payload version 2")
- err = registerProducer.SerializeUnsigned(rpSignBuf, payload.ProducerInfoSchnorrVersion)
+ err = registerProducer.SerializeUnsigned(rpSignBuf, byte(payloadversion))
if err != nil {
fmt.Println(err)
os.Exit(1)
@@ -1019,42 +1026,45 @@ func RegisterCancelProducerType(L *lua.LState) {
// Constructor
func newProcessProducer(L *lua.LState) int {
publicKeyStr := L.ToString(1)
- client, err := checkClient(L, 2)
+ payloadversion := L.ToInt(2)
+ client, err := checkClient(L, 3)
if err != nil {
fmt.Println(err)
}
-
+ fmt.Println("payloadversion", payloadversion)
publicKey, err := common.HexStringToBytes(publicKeyStr)
if err != nil {
fmt.Println("wrong producer public key")
os.Exit(1)
}
processProducer := &payload.ProcessProducer{
- OwnerPublicKey: []byte(publicKey),
+ OwnerKey: []byte(publicKey),
}
cpSignBuf := new(bytes.Buffer)
- err = processProducer.SerializeUnsigned(cpSignBuf, payload.ProcessProducerVersion)
+ err = processProducer.SerializeUnsigned(cpSignBuf, byte(payloadversion))
if err != nil {
fmt.Println(err)
os.Exit(1)
}
- codeHash, err := contract.PublicKeyToStandardCodeHash(publicKey)
- if err != nil {
- fmt.Println(err)
- os.Exit(1)
- }
- acc := client.GetAccountByCodeHash(*codeHash)
- if acc == nil {
- fmt.Println("no available account in wallet")
- os.Exit(1)
- }
- rpSig, err := crypto.Sign(acc.PrivKey(), cpSignBuf.Bytes())
- if err != nil {
- fmt.Println(err)
- os.Exit(1)
+ if payloadversion == int(payload.ProcessProducerVersion) {
+ codeHash, err := state.GetOwnerKeyCodeHash(publicKey)
+ if err != nil {
+ fmt.Println(err)
+ os.Exit(1)
+ }
+ acc := client.GetAccountByCodeHash(*codeHash)
+ if acc == nil {
+ fmt.Println("no available account in wallet")
+ os.Exit(1)
+ }
+ rpSig, err := crypto.Sign(acc.PrivKey(), cpSignBuf.Bytes())
+ if err != nil {
+ fmt.Println(err)
+ os.Exit(1)
+ }
+ processProducer.Signature = rpSig
}
- processProducer.Signature = rpSig
ud := L.NewUserData()
ud.Value = processProducer
@@ -1125,7 +1135,7 @@ func newCancelProducerSchnorr(L *lua.LState) int {
os.Exit(1)
}
processProducer := &payload.ProcessProducer{
- OwnerPublicKey: []byte(publicKey),
+ OwnerKey: []byte(publicKey),
}
cpSignBuf := new(bytes.Buffer)
@@ -1357,11 +1367,71 @@ func RegisterRegisterCRType(L *lua.LState) {
// Constructor
func newRegisterCR(L *lua.LState) int {
- publicKeyStr := L.ToString(1)
- nickName := L.ToString(2)
- url := L.ToString(3)
- location := L.ToInt64(4)
- payloadVersion := byte(L.ToInt(5))
+ payloadVersion := byte(L.ToInt(1))
+
+ // multi sign
+ if payloadVersion == payload.CRInfoMultiSignVersion {
+ nickName := L.ToString(2)
+ url := L.ToString(3)
+ location := L.ToInt64(4)
+ m := L.ToInt(5)
+ client, err := checkClient(L, 6)
+
+ var code []byte
+ var pks []*crypto.PublicKey
+ accs := client.GetAccounts()
+ for _, acc := range accs {
+ if acc.PublicKey == nil {
+ continue
+ }
+ pks = append(pks, acc.PublicKey)
+ }
+ fmt.Println("pks:", len(pks), pks)
+
+ multiCode, err := contract.CreateMultiSigRedeemScript(int(m), pks)
+ if err != nil {
+ fmt.Println(err)
+ return 0
+ }
+ code = multiCode
+
+ ct, err := contract.CreateCRIDContractByCode(code)
+ if err != nil {
+ fmt.Println("wrong cr public key")
+ os.Exit(1)
+ }
+
+ didCode := make([]byte, len(code))
+ copy(didCode, code)
+ didCode = append(didCode[:len(code)-1], common.DID)
+ didCT, err := contract.CreateCRIDContractByCode(didCode)
+ if err != nil {
+ fmt.Println("wrong cr public key")
+ os.Exit(1)
+ }
+
+ registerCR := &payload.CRInfo{
+ CID: *ct.ToProgramHash(),
+ DID: *didCT.ToProgramHash(),
+ NickName: nickName,
+ Url: url,
+ Location: uint64(location),
+ }
+ fmt.Println("pld:", registerCR)
+
+ ud := L.NewUserData()
+ ud.Value = registerCR
+ L.SetMetatable(ud, L.GetTypeMetatable(luaRegisterCRName))
+ L.Push(ud)
+
+ return 1
+ }
+
+ // normal sign or schnorr sign (old logic)
+ publicKeyStr := L.ToString(2)
+ nickName := L.ToString(3)
+ url := L.ToString(4)
+ location := L.ToInt64(5)
needSign := true
var account *account.SchnorAccount
client, err := checkClient(L, 6)
@@ -1472,7 +1542,6 @@ func newRegisterCR(L *lua.LState) int {
//}
//registerCR.Signature = rpSig[:]
}
-
}
ud := L.NewUserData()
@@ -1518,11 +1587,69 @@ func RegisterUpdateCRType(L *lua.LState) {
// Constructor
func newUpdateCR(L *lua.LState) int {
- publicKeyStr := L.ToString(1)
- nickName := L.ToString(2)
- url := L.ToString(3)
- location := L.ToInt64(4)
- payloadVersion := byte(L.ToInt(5))
+ payloadVersion := byte(L.ToInt(1))
+ // multi sign
+ if payloadVersion == payload.CRInfoMultiSignVersion {
+ nickName := L.ToString(2)
+ url := L.ToString(3)
+ location := L.ToInt64(4)
+ m := L.ToInt(5)
+ client, err := checkClient(L, 6)
+
+ var code []byte
+ var pks []*crypto.PublicKey
+ accs := client.GetAccounts()
+ for _, acc := range accs {
+ if acc.PublicKey == nil {
+ continue
+ }
+ pks = append(pks, acc.PublicKey)
+ }
+ fmt.Println("pks:", len(pks), pks)
+
+ multiCode, err := contract.CreateMultiSigRedeemScript(int(m), pks)
+ if err != nil {
+ fmt.Println(err)
+ return 0
+ }
+ code = multiCode
+
+ ct, err := contract.CreateCRIDContractByCode(code)
+ if err != nil {
+ fmt.Println("wrong cr public key")
+ os.Exit(1)
+ }
+
+ didCode := make([]byte, len(code))
+ copy(didCode, code)
+ didCode = append(didCode[:len(code)-1], common.DID)
+ didCT, err := contract.CreateCRIDContractByCode(didCode)
+ if err != nil {
+ fmt.Println("wrong cr public key")
+ os.Exit(1)
+ }
+
+ updateCR := &payload.CRInfo{
+ CID: *ct.ToProgramHash(),
+ DID: *didCT.ToProgramHash(),
+ NickName: nickName,
+ Url: url,
+ Location: uint64(location),
+ }
+ fmt.Println("pld:", updateCR)
+
+ ud := L.NewUserData()
+ ud.Value = updateCR
+ L.SetMetatable(ud, L.GetTypeMetatable(luaUpdateCRName))
+ L.Push(ud)
+
+ return 1
+ }
+
+ publicKeyStr := L.ToString(2)
+ nickName := L.ToString(3)
+ url := L.ToString(4)
+ location := L.ToInt64(5)
needSign := true
client, err := checkClient(L, 6)
if err != nil {
@@ -1655,6 +1782,7 @@ func RegisterUnregisterCRType(L *lua.LState) {
L.SetGlobal("unregistercr", mt)
// static attributes
L.SetField(mt, "new", L.NewFunction(newUnregisterCR))
+ L.SetField(mt, "newmulti", L.NewFunction(newMultiUnregisterCR))
// methods
L.SetField(mt, "__index", L.SetFuncs(L.NewTable(), unregisterCRMethods))
}
@@ -1744,6 +1872,47 @@ func newUnregisterCR(L *lua.LState) int {
return 1
}
+// Constructor
+func newMultiUnregisterCR(L *lua.LState) int {
+ m := L.ToInt(1)
+ client, err := checkClient(L, 2)
+
+ var code []byte
+ var pks []*crypto.PublicKey
+ accs := client.GetAccounts()
+ for _, acc := range accs {
+ if acc.PublicKey == nil {
+ continue
+ }
+ pks = append(pks, acc.PublicKey)
+ }
+ fmt.Println("pks:", len(pks), pks)
+
+ multiCode, err := contract.CreateMultiSigRedeemScript(m, pks)
+ if err != nil {
+ fmt.Println(err)
+ return 0
+ }
+ code = multiCode
+
+ ct, err := contract.CreateCRIDContractByCode(code)
+ if err != nil {
+ fmt.Println("wrong code")
+ os.Exit(1)
+ }
+
+ unregisterCR := &payload.UnregisterCR{
+ CID: *ct.ToProgramHash(),
+ }
+
+ ud := L.NewUserData()
+ ud.Value = unregisterCR
+ L.SetMetatable(ud, L.GetTypeMetatable(luaUnregisterCRName))
+ L.Push(ud)
+
+ return 1
+}
+
// Checks whether the first lua argument is a *LUserData with *CRInfo and
// returns this *CRInfo.
func checkUnregisterCR(L *lua.LState, idx int) *payload.UnregisterCR {
@@ -1874,7 +2043,7 @@ func newSecretaryGeneralProposal(L *lua.LState) int {
crcProposal := &payload.CRCProposal{
ProposalType: payload.CRCProposalType(proposalType),
- OwnerPublicKey: ownPublicKey,
+ OwnerKey: ownPublicKey,
DraftData: []byte(draftDataStr),
DraftHash: draftHash,
SecretaryGeneralPublicKey: secretaryGeneralPublicKey,
@@ -1994,7 +2163,7 @@ func newCRCProposal(L *lua.LState) int {
did, _ := getDIDFromCode(ct.Code)
crcProposal := &payload.CRCProposal{
ProposalType: payload.CRCProposalType(proposalType),
- OwnerPublicKey: publicKey,
+ OwnerKey: publicKey,
DraftHash: draftHash,
DraftData: []byte(draftDataStr),
Budgets: budgets,
@@ -2124,12 +2293,12 @@ func newCRChangeProposalOwner(L *lua.LState) int {
crcProposal := &payload.CRCProposal{
ProposalType: payload.CRCProposalType(proposalType),
- OwnerPublicKey: ownerPublicKey,
+ OwnerKey: ownerPublicKey,
Recipient: *recipient,
DraftHash: draftHash,
DraftData: []byte(draftDataStr),
TargetProposalHash: *targetHash,
- NewOwnerPublicKey: newOwnerPublicKey,
+ NewOwnerKey: newOwnerPublicKey,
CRCouncilMemberDID: *CRCouncilMemberDID,
NewOwnerSignature: []byte{},
}
@@ -2233,9 +2402,9 @@ func newCRCRegisterSideChainProposalHash(L *lua.LState) int {
}
did, _ := getDIDFromCode(ct.Code)
crcProposal := &payload.CRCProposal{
- ProposalType: payload.CRCProposalType(proposalType),
- OwnerPublicKey: publicKey,
- DraftHash: *draftHash,
+ ProposalType: payload.CRCProposalType(proposalType),
+ OwnerKey: publicKey,
+ DraftHash: *draftHash,
SideChainInfo: payload.SideChainInfo{
SideChainName: sideChainName,
MagicNumber: uint32(magicNumber),
@@ -2335,7 +2504,7 @@ func newCRCChangeCustomIDFee(L *lua.LState) int {
}
crcProposal := &payload.CRCProposal{
ProposalType: payload.ChangeCustomIDFee,
- OwnerPublicKey: publicKey,
+ OwnerKey: publicKey,
DraftHash: draftHash,
DraftData: []byte(draftDataStr),
CustomIDFeeRateInfo: payload.CustomIDFeeRateInfo{RateOfCustomIDFee: *rate},
@@ -2432,7 +2601,7 @@ func newCRCReceivedCustomID(L *lua.LState) int {
crcProposal := &payload.CRCProposal{
ProposalType: payload.CRCProposalType(proposalType),
- OwnerPublicKey: publicKey,
+ OwnerKey: publicKey,
DraftHash: draftHash,
DraftData: []byte(draftDataStr),
CRCouncilMemberDID: *did,
@@ -2524,7 +2693,7 @@ func newCRCReservedCustomID(L *lua.LState) int {
did, _ := getDIDFromCode(ct.Code)
crcProposal := &payload.CRCProposal{
ProposalType: payload.CRCProposalType(proposalType),
- OwnerPublicKey: publicKey,
+ OwnerKey: publicKey,
DraftHash: draftHash,
DraftData: []byte(draftDataStr),
CRCouncilMemberDID: *did,
@@ -2620,7 +2789,7 @@ func newCRCCloseProposalHash(L *lua.LState) int {
did, _ := getDIDFromCode(ct.Code)
crcProposal := &payload.CRCProposal{
ProposalType: payload.CRCProposalType(proposalType),
- OwnerPublicKey: publicKey,
+ OwnerKey: publicKey,
DraftHash: draftHash,
DraftData: []byte(draftDataStr),
TargetProposalHash: *closeProposalHash,
@@ -2865,8 +3034,8 @@ func newCRCProposalTracking(L *lua.LState) int {
MessageHash: *MessageHash,
SecretaryGeneralOpinionHash: *opinionHash,
Stage: uint8(stage),
- OwnerPublicKey: ownerpublickey,
- NewOwnerPublicKey: newownerpublickey,
+ OwnerKey: ownerpublickey,
+ NewOwnerKey: newownerpublickey,
OwnerSignature: []byte{},
NewOwnerSignature: []byte{},
SecretaryGeneralSignature: []byte{},
@@ -2976,7 +3145,7 @@ func newCRCProposalWithdraw(L *lua.LState) int {
os.Exit(1)
}
pubkey := getPublicKeyFromCode(acc.RedeemScript)
- crcProposalWithdraw.OwnerPublicKey = pubkey
+ crcProposalWithdraw.OwnerKey = pubkey
if payloadversion == 1 {
r, err := common.Uint168FromAddress(receipt)
if err != nil {
diff --git a/cmd/script/api/txtype.go b/cmd/script/api/txtype.go
index 626eb46eb..f5ae1a8c9 100644
--- a/cmd/script/api/txtype.go
+++ b/cmd/script/api/txtype.go
@@ -21,6 +21,7 @@ import (
"github.com/elastos/Elastos.ELA/core/types/interfaces"
"github.com/elastos/Elastos.ELA/core/types/payload"
"github.com/elastos/Elastos.ELA/crypto"
+ "github.com/elastos/Elastos.ELA/dpos/state"
"github.com/elastos/Elastos.ELA/servers"
"github.com/elastos/Elastos.ELA/utils/http"
@@ -40,14 +41,15 @@ func RegisterTransactionType(L *lua.LState) {
}
// Constructor
-// Version TransactionVersion
-// TxType TxType
-// PayloadVersion byte
-// Payload Payload
-// Attributes []*Attribute
-// Inputs []*Input
-// Outputs []*Output
-// LockTime uint32
+//
+// Version TransactionVersion
+// TxType TxType
+// PayloadVersion byte
+// Payload Payload
+// Attributes []*Attribute
+// Inputs []*Input
+// Outputs []*Output
+// LockTime uint32
func newTransaction(L *lua.LState) int {
version := L.ToInt(1)
txType := common2.TxType(L.ToInt(2))
@@ -183,19 +185,21 @@ func checkTransaction(L *lua.LState, idx int) interfaces.Transaction {
}
var transactionMethods = map[string]lua.LGFunction{
- "appendtxin": txAppendInput,
- "appendtxout": txAppendOutput,
- "appendattr": txAppendAttribute,
- "get": txGet,
- "sign": signTx,
- "multisign": multiSignTx,
- "signschnorr": signSchnorrTx,
- "hash": txHash,
- "serialize": serialize,
- "deserialize": deserialize,
- "appendenough": appendEnough,
- "appendprogram": appendProgram,
- "signpayload": signPayload,
+ "appendtxin": txAppendInput,
+ "appendtxout": txAppendOutput,
+ "appendattr": txAppendAttribute,
+ "get": txGet,
+ "sign": signTx,
+ "multisign": multiSignTx,
+ "signschnorr": signSchnorrTx,
+ "hash": txHash,
+ "serialize": serialize,
+ "deserialize": deserialize,
+ "appendenough": appendEnough,
+ "appendenoughmultiinput": appendEnoughMultiInput,
+ "appendprogram": appendProgram,
+ "signpayload": signPayload,
+ "multiprogramssigntx": multiProgramsSignTx,
}
func signPayload(L *lua.LState) int {
@@ -217,8 +221,7 @@ func signPayload(L *lua.LState) int {
if err := producerInfo.SerializeUnsigned(rpSignBuf, payload.ProducerInfoVersion); err != nil {
cmdcom.PrintErrorAndExit(err.Error())
}
-
- codeHash, err := contract.PublicKeyToStandardCodeHash(producerInfo.OwnerPublicKey)
+ codeHash, err := state.GetOwnerKeyCodeHash(producerInfo.OwnerKey)
if err != nil {
cmdcom.PrintErrorAndExit(err.Error())
}
@@ -298,6 +301,9 @@ func multiSignTx(L *lua.LState) int {
pks := make([]*crypto.PublicKey, 0)
accs := client.GetAccounts()
for _, acc := range accs {
+ if acc.PublicKey == nil {
+ continue
+ }
pks = append(pks, acc.PublicKey)
}
@@ -350,6 +356,34 @@ func signTx(L *lua.LState) int {
return 0
}
+func multiProgramsSignTx(L *lua.LState) int {
+ txn := checkTransaction(L, 1)
+ client, err := checkClient(L, 2)
+ if err != nil {
+ fmt.Println(err)
+ os.Exit(1)
+ }
+
+ var programs []*pg.Program
+ for _, account := range client.GetAccounts() {
+ program := pg.Program{
+ Code: account.RedeemScript,
+ Parameter: []byte{},
+ }
+ programs = append(programs, &program)
+ }
+
+ txn.SetPrograms(programs)
+
+ txn, err = client.Sign(txn)
+ if err != nil {
+ fmt.Println(err)
+ os.Exit(1)
+ }
+
+ return 0
+}
+
func signSchnorrTx(L *lua.LState) int {
txn := checkTransaction(L, 1)
account, err := checkAccount(L, 2)
@@ -466,6 +500,72 @@ func appendEnough(L *lua.LState) int {
return 1
}
+func appendEnoughMultiInput(L *lua.LState) int {
+ txn := checkTransaction(L, 1)
+ from := L.ToString(2)
+ totalAmount := L.ToInt64(3)
+ result, err := cmdcom.RPCCall("listunspent", http.Params{
+ "addresses": []string{from},
+ })
+ if err != nil {
+ fmt.Println(err)
+ os.Exit(1)
+ }
+ data, err := json.Marshal(result)
+ if err != nil {
+ fmt.Println(err)
+ os.Exit(1)
+ }
+ var utxos []servers.UTXOInfo
+ err = json.Unmarshal(data, &utxos)
+
+ var availabelUtxos []servers.UTXOInfo
+ for _, utxo := range utxos {
+ if common2.TxType(utxo.TxType) == common2.CoinBase && utxo.Confirmations < 101 {
+ continue
+ }
+ availabelUtxos = append(availabelUtxos, utxo)
+ }
+
+ //totalAmount := common.Fixed64(0)
+ var charge int64
+ // Create transaction inputs
+ var txInputs []*common2.Input // The inputs in transaction
+ for _, utxo := range availabelUtxos {
+ txIDReverse, _ := hex.DecodeString(utxo.TxID)
+ txID, _ := common.Uint256FromBytes(common.BytesReverse(txIDReverse))
+ input := &common2.Input{
+ Previous: common2.OutPoint{
+ TxID: *txID,
+ Index: uint16(utxo.VOut),
+ },
+ Sequence: 4294967295,
+ }
+ txInputs = append(txInputs, input)
+ amount, _ := common.StringToFixed64(utxo.Amount)
+ if int64(*amount) < totalAmount {
+ totalAmount -= int64(*amount)
+ } else if int64(*amount) == totalAmount {
+ totalAmount = 0
+ break
+ } else if int64(*amount) > totalAmount {
+ charge = int64(*amount) - totalAmount
+ totalAmount = 0
+ break
+ }
+ }
+
+ if totalAmount > 0 {
+ fmt.Println("[Wallet], Available token is not enough")
+ os.Exit(1)
+ }
+
+ txn.SetInputs(append(txn.Inputs(), txInputs...))
+ L.Push(lua.LNumber(charge))
+
+ return 1
+}
+
func appendProgram(L *lua.LState) int {
txn := checkTransaction(L, 1)
program := checkProgram(L, 2)
diff --git a/cmd/script/script.go b/cmd/script/script.go
index 9abbb7e26..33139df54 100644
--- a/cmd/script/script.go
+++ b/cmd/script/script.go
@@ -19,6 +19,7 @@ import (
func registerParams(c *cli.Context, L *lua.LState) {
wallet := c.String("wallet")
+ addresses := c.String("addresses")
password := c.String("password")
code := c.String("code")
publicKey := c.String("publickey")
@@ -96,6 +97,17 @@ func registerParams(c *cli.Context, L *lua.LState) {
L.Push(lua.LString(wallet))
return 1
}
+ //get_addresses
+ getAddresses := func(L *lua.LState) int {
+ table := L.NewTable()
+ L.SetMetatable(table, L.GetTypeMetatable("addresses"))
+ cs := strings.Split(addresses, ",")
+ for _, c := range cs {
+ table.Append(lua.LString(c))
+ }
+ L.Push(table)
+ return 1
+ }
getPassword := func(L *lua.LState) int {
L.Push(lua.LString(password))
return 1
@@ -391,7 +403,7 @@ func registerParams(c *cli.Context, L *lua.LState) {
L.Push(lua.LString(stakeAddress))
return 1
}
-
+ L.Register("getAddresses", getAddresses)
L.Register("getWallet", getWallet)
L.Register("getPassword", getPassword)
L.Register("getDepositAddr", getDepositAddr)
@@ -534,6 +546,10 @@ func NewCommand() *cli.Command {
Name: "privatekeys, priks",
Usage: "set the private key",
},
+ cli.StringFlag{
+ Name: "addresses",
+ Usage: "set the addresses",
+ },
cli.StringFlag{
Name: "publickeys, pubs",
Usage: "set the pub keys",
diff --git a/cmd/wallet/account.go b/cmd/wallet/account.go
index 10b5ac448..0a84f7a2f 100644
--- a/cmd/wallet/account.go
+++ b/cmd/wallet/account.go
@@ -380,6 +380,7 @@ func generateDposV2Address(c *cli.Context) error {
if err != nil {
return err
}
+
} else {
programHash, err = common.Uint168FromAddress(addr)
if err != nil {
@@ -403,10 +404,6 @@ func generateDposV2Address(c *cli.Context) error {
}
func generateDepositAddress(c *cli.Context) error {
- if c.NArg() < 1 {
- cmdcom.PrintErrorMsg("Missing argument. Standard address expected.")
- cli.ShowCommandHelpAndExit(c, "depositaddress", 1)
- }
addr := c.Args().First()
var programHash *common.Uint168
@@ -431,10 +428,6 @@ func generateDepositAddress(c *cli.Context) error {
}
}
- if contract.GetPrefixType(*programHash) != contract.PrefixStandard {
- return errors.New("standard address expected")
- }
-
codeHash := programHash.ToCodeHash()
depositHash := common.Uint168FromCodeHash(byte(contract.PrefixDeposit), codeHash)
address, err := depositHash.ToAddress()
diff --git a/cmd/wallet/producer.go b/cmd/wallet/producer.go
index ec02767b5..270027814 100644
--- a/cmd/wallet/producer.go
+++ b/cmd/wallet/producer.go
@@ -16,6 +16,7 @@ import (
"github.com/elastos/Elastos.ELA/core/types/functions"
"github.com/elastos/Elastos.ELA/core/types/interfaces"
"github.com/elastos/Elastos.ELA/core/types/payload"
+ "github.com/elastos/Elastos.ELA/dpos/state"
"github.com/urfave/cli"
)
@@ -69,7 +70,7 @@ func createProducerInfoCommonTransaction(c *cli.Context, txType common2.TxType,
return errors.New("invalid transaction amount")
}
- programHash, err := contract.PublicKeyToDepositProgramHash(ownerPublicKey)
+ programHash, err := state.GetOwnerKeyDepositProgramHash(ownerPublicKey)
if err != nil {
return err
}
@@ -122,13 +123,13 @@ func createProducerInfoCommonTransaction(c *cli.Context, txType common2.TxType,
}
p := &payload.ProducerInfo{
- OwnerPublicKey: ownerPublicKey,
- NodePublicKey: nodePublicKey,
- NickName: nickName,
- Url: url,
- Location: locationCode,
- NetAddress: netAddress,
- StakeUntil: uint32(stakeUntil),
+ OwnerKey: ownerPublicKey,
+ NodePublicKey: nodePublicKey,
+ NickName: nickName,
+ Url: url,
+ Location: locationCode,
+ NetAddress: netAddress,
+ StakeUntil: uint32(stakeUntil),
}
rpSignBuf := new(bytes.Buffer)
@@ -200,7 +201,7 @@ func createUnregisterProducerTransaction(c *cli.Context) error {
outputs := make([]*OutputInfo, 0)
p := &payload.ProcessProducer{
- OwnerPublicKey: ownerPublicKey,
+ OwnerKey: ownerPublicKey,
}
rpSignBuf := new(bytes.Buffer)
diff --git a/cmd/wallet/proposal.go b/cmd/wallet/proposal.go
index debdbe025..b4dc79a2a 100644
--- a/cmd/wallet/proposal.go
+++ b/cmd/wallet/proposal.go
@@ -212,13 +212,13 @@ func payloadProposalNormalOwnerUnsigned(c *cli.Context) error {
}
p := &payload.CRCProposal{
- ProposalType: payload.Normal,
- CategoryData: categoryData,
- OwnerPublicKey: ownerPublicKey,
- DraftHash: *draftHash,
- DraftData: draftData,
- Budgets: budgets,
- Recipient: *recipient,
+ ProposalType: payload.Normal,
+ CategoryData: categoryData,
+ OwnerKey: ownerPublicKey,
+ DraftHash: *draftHash,
+ DraftData: draftData,
+ Budgets: budgets,
+ Recipient: *recipient,
}
w := new(bytes.Buffer)
@@ -368,12 +368,12 @@ func payloadProposalTrackingOwnerUnsigned(c *cli.Context) error {
}
p := &payload.CRCProposalTracking{
- ProposalHash: *proposalHash,
- MessageHash: *messageHash,
- MessageData: messageData,
- Stage: uint8(stage),
- OwnerPublicKey: ownerPubKey,
- NewOwnerPublicKey: newOwnerPublicKey,
+ ProposalHash: *proposalHash,
+ MessageHash: *messageHash,
+ MessageData: messageData,
+ Stage: uint8(stage),
+ OwnerKey: ownerPubKey,
+ NewOwnerKey: newOwnerPublicKey,
}
pSignBuf := new(bytes.Buffer)
@@ -636,7 +636,7 @@ func payloadProposalSecretaryGeneralElectionUnsigned(c *cli.Context) error {
p := &payload.CRCProposal{
ProposalType: payload.SecretaryGeneral,
CategoryData: categoryData,
- OwnerPublicKey: ownerPublicKey,
+ OwnerKey: ownerPublicKey,
DraftHash: *draftHash,
DraftData: draftData,
SecretaryGeneralPublicKey: secretaryPubKey,
@@ -825,12 +825,12 @@ func payloadProposalChangeOwnerUnsigned(c *cli.Context) error {
p := &payload.CRCProposal{
ProposalType: payload.ChangeProposalOwner,
CategoryData: categoryData,
- OwnerPublicKey: ownerPublicKey,
+ OwnerKey: ownerPublicKey,
DraftHash: *draftHash,
DraftData: draftData,
TargetProposalHash: *targetProposalHash,
NewRecipient: *recipient,
- NewOwnerPublicKey: newOwnerPublicKey,
+ NewOwnerKey: newOwnerPublicKey,
}
w := new(bytes.Buffer)
@@ -1003,7 +1003,7 @@ func payloadProposalTerminateOwnerUnsigned(c *cli.Context) error {
p := &payload.CRCProposal{
ProposalType: payload.CloseProposal,
CategoryData: categoryData,
- OwnerPublicKey: ownerPublicKey,
+ OwnerKey: ownerPublicKey,
DraftHash: *draftHash,
DraftData: draftData,
TargetProposalHash: *targetProposalHash,
@@ -1055,7 +1055,7 @@ func payloadProposalReserverCustomIDOwnerUnsigned(c *cli.Context) error {
p := &payload.CRCProposal{
ProposalType: payload.ReserveCustomID,
CategoryData: categoryData,
- OwnerPublicKey: ownerPublicKey,
+ OwnerKey: ownerPublicKey,
DraftHash: *draftHash,
DraftData: draftData,
ReservedCustomIDList: reservedCustomIDList,
@@ -1113,7 +1113,7 @@ func payloadProposalReceiveCustomIDOwnerUnsigned(c *cli.Context) error {
p := &payload.CRCProposal{
ProposalType: payload.ReceiveCustomID,
CategoryData: categoryData,
- OwnerPublicKey: ownerPublicKey,
+ OwnerKey: ownerPublicKey,
DraftHash: *draftHash,
DraftData: draftData,
ReceivedCustomIDList: receivedCustomIDList,
@@ -1180,7 +1180,7 @@ func payloadProposalChangeCustomIDFeeOwnerUnsigned(c *cli.Context) error {
p := &payload.CRCProposal{
ProposalType: payload.ChangeCustomIDFee,
CategoryData: categoryData,
- OwnerPublicKey: ownerPublicKey,
+ OwnerKey: ownerPublicKey,
DraftHash: *draftHash,
DraftData: draftData,
CustomIDFeeRateInfo: customIDFeeRate,
@@ -1257,12 +1257,12 @@ func payloadProposalRegisterSidechainOwnerUnsigned(c *cli.Context) error {
}
p := &payload.CRCProposal{
- ProposalType: payload.RegisterSideChain,
- CategoryData: categoryData,
- OwnerPublicKey: ownerPublicKey,
- DraftHash: *draftHash,
- DraftData: draftData,
- SideChainInfo: sidechainInfo,
+ ProposalType: payload.RegisterSideChain,
+ CategoryData: categoryData,
+ OwnerKey: ownerPublicKey,
+ DraftHash: *draftHash,
+ DraftData: draftData,
+ SideChainInfo: sidechainInfo,
}
w := new(bytes.Buffer)
@@ -1307,10 +1307,10 @@ func payloadProposalWithdraw(c *cli.Context) error {
}
p := payload.CRCProposalWithdraw{
- ProposalHash: *proposalHash,
- OwnerPublicKey: ownerPublicKey,
- Recipient: *recipient,
- Amount: *amount,
+ ProposalHash: *proposalHash,
+ OwnerKey: ownerPublicKey,
+ Recipient: *recipient,
+ Amount: *amount,
}
w := new(bytes.Buffer)
diff --git a/common/config/config.go b/common/config/config.go
index 44c155ba3..b2d87e3a6 100644
--- a/common/config/config.go
+++ b/common/config/config.go
@@ -180,6 +180,9 @@ func GetDefaultParams() *Configuration {
MaxInactiveRoundsOfRandomNode: 36 * 8,
RevertToPOWNoBlockTime: 12 * 3600,
StopConfirmBlockTime: 11 * 3600,
+ RevertToPOWNoBlockTimeV1: 2 * 3600,
+ StopConfirmBlockTimeV1: 6600,
+ ChangeViewV1Height: 1911200,
DPoSV2IllegalPenalty: 20000000000,
DPOSNodeCrossChainHeight: math.MaxUint32,
DPoSV2DepositCoinMinLockTime: 7200,
@@ -196,6 +199,8 @@ func GetDefaultParams() *Configuration {
NFTStartHeight: 1405000,
SponsorsFilePath: "sponsors",
RecordSponsorStartHeight: 1801550,
+ NFTV2StartHeight: math.MaxUint32, // todo complete me
+ DexStartHeight: math.MaxUint32, // todo complete me
OriginArbiters: []string{
"0248df6705a909432be041e0baa25b8f648741018f70d1911f2ed28778db4b8fe4",
"02771faf0f4d4235744b30972d5f2c470993920846c761e4d08889ecfdc061cddf",
@@ -256,6 +261,8 @@ func GetDefaultParams() *Configuration {
VotesSchnorrStartHeight: math.MaxUint32,
CrossChainMonitorStartHeight: math.MaxUint32,
CrossChainMonitorInterval: 100,
+ SupportMultiCodeHeight: math.MaxUint32, // todo complete me
+ MultiExchangeVotesStartHeight: math.MaxUint32, // todo complete me
HttpInfoPort: 20333,
HttpRestPort: 20334,
HttpWsPort: 20335,
@@ -354,10 +361,13 @@ func (p *Configuration) TestNet() *Configuration {
p.DPoSConfiguration.NoCRCDPOSNodeHeight = 815060
p.DPoSConfiguration.RandomCandidatePeriod = 36 * 10
p.DPoSConfiguration.MaxInactiveRoundsOfRandomNode = 36 * 8
- p.DPoSConfiguration.DPOSNodeCrossChainHeight = 2000000 // todo complete me
+ p.DPoSConfiguration.DPOSNodeCrossChainHeight = math.MaxUint32 // todo complete me
p.MaxReservedCustomIDLength = 255
p.DPoSConfiguration.RevertToPOWNoBlockTime = 12 * 3600
p.DPoSConfiguration.StopConfirmBlockTime = 11 * 3600
+ p.DPoSConfiguration.RevertToPOWNoBlockTimeV1 = 2 * 3600
+ p.DPoSConfiguration.StopConfirmBlockTimeV1 = 6600
+ p.DPoSConfiguration.ChangeViewV1Height = 1304005
p.DPoSConfiguration.RevertToPOWStartHeight = 815060
p.HalvingRewardHeight = 877880 //767000 + 154 * 720
p.HalvingRewardInterval = 1051200 //4 * 365 * 720
@@ -370,6 +380,7 @@ func (p *Configuration) TestNet() *Configuration {
p.ProhibitTransferToDIDHeight = 807000
p.DIDSideChainAddress = "XKUh4GLhFJiqAMTF6HyWQrV9pK9HcGUdfJ"
p.DPoSV2StartHeight = 965800 + 720*3
+ p.SupportMultiCodeHeight = 2000
p.DPoSV2EffectiveVotes = 3000 * 100000000
p.DPoSConfiguration.DPoSV2DepositCoinMinLockTime = 7200 * 3
p.DPoSConfiguration.DPoSV2MinVotesLockTime = 7200
@@ -384,6 +395,8 @@ func (p *Configuration) TestNet() *Configuration {
p.DPoSConfiguration.NFTStartHeight = 1098000
p.DPoSConfiguration.SponsorsFilePath = "sponsors"
p.DPoSConfiguration.RecordSponsorStartHeight = 1174500
+ p.DPoSConfiguration.NFTV2StartHeight = math.MaxUint32 // todo complete me
+ p.DPoSConfiguration.DexStartHeight = math.MaxUint32 // todo complete me
p.HttpInfoPort = 21333
p.HttpRestPort = 21334
@@ -392,6 +405,7 @@ func (p *Configuration) TestNet() *Configuration {
p.ProducerSchnorrStartHeight = math.MaxUint32
p.CRSchnorrStartHeight = math.MaxUint32
p.VotesSchnorrStartHeight = math.MaxUint32
+ p.MultiExchangeVotesStartHeight = math.MaxUint32 // todo complete me
p.MemoryPoolTxMaximumStayHeight = 10
@@ -476,10 +490,13 @@ func (p *Configuration) RegNet() *Configuration {
p.DPoSConfiguration.NoCRCDPOSNodeHeight = 706240
p.DPoSConfiguration.RandomCandidatePeriod = 36 * 10
p.DPoSConfiguration.MaxInactiveRoundsOfRandomNode = 36 * 8
- p.DPoSConfiguration.DPOSNodeCrossChainHeight = 2000000 // todo complete me
+ p.DPoSConfiguration.DPOSNodeCrossChainHeight = math.MaxUint32 // todo complete me
p.MaxReservedCustomIDLength = 255
p.DPoSConfiguration.RevertToPOWNoBlockTime = 12 * 3600
p.DPoSConfiguration.StopConfirmBlockTime = 11 * 3600
+ p.DPoSConfiguration.RevertToPOWNoBlockTimeV1 = 2 * 3600 // todo complete me
+ p.DPoSConfiguration.StopConfirmBlockTimeV1 = 6600 // todo complete me
+ p.DPoSConfiguration.ChangeViewV1Height = math.MaxUint32 // todo complete me
p.DPoSConfiguration.RevertToPOWStartHeight = 706240
p.HalvingRewardHeight = 801240 //690360 + 154 * 720
p.HalvingRewardInterval = 1051200 //4 * 365 * 720
@@ -492,6 +509,7 @@ func (p *Configuration) RegNet() *Configuration {
p.ProhibitTransferToDIDHeight = 730000
p.DIDSideChainAddress = "XKUh4GLhFJiqAMTF6HyWQrV9pK9HcGUdfJ"
p.DPoSV2StartHeight = 875544 + 720*2
+ p.SupportMultiCodeHeight = 2000
p.DPoSV2EffectiveVotes = 300000000000
p.DPoSConfiguration.DPoSV2DepositCoinMinLockTime = 7200 * 3
p.DPoSConfiguration.DPoSV2MinVotesLockTime = 7200
@@ -506,6 +524,7 @@ func (p *Configuration) RegNet() *Configuration {
p.DPoSConfiguration.NFTStartHeight = 968000
p.DPoSConfiguration.SponsorsFilePath = "sponsors"
p.DPoSConfiguration.RecordSponsorStartHeight = math.MaxUint32
+ p.DPoSConfiguration.NFTV2StartHeight = math.MaxUint32 // todo complete me
p.HttpInfoPort = 22333
p.HttpRestPort = 22334
p.HttpWsPort = 22335
@@ -513,6 +532,8 @@ func (p *Configuration) RegNet() *Configuration {
p.ProducerSchnorrStartHeight = math.MaxUint32
p.CRSchnorrStartHeight = math.MaxUint32
p.VotesSchnorrStartHeight = math.MaxUint32
+ p.MultiExchangeVotesStartHeight = math.MaxUint32 // todo complete me
+ p.DPoSConfiguration.DexStartHeight = math.MaxUint32 // todo complete me
p.MemoryPoolTxMaximumStayHeight = 10
@@ -629,6 +650,8 @@ type Configuration struct {
ReturnCrossChainCoinStartHeight uint32 `screw:"--returncrosschaincoinstartheight" usage:"defines the start height to support ReturnCrossChainDepositCoin transaction"`
// DPoSV2StartHeight defines the start height of dpos 2.0.
DPoSV2StartHeight uint32 `screw:"--dposv2startheight" usage:"defines the start height to support DPoSV2 transaction"`
+ // multicode support height
+ SupportMultiCodeHeight uint32 `screw:"--supportmulticodeheight" usage:"defines the support height of multicode transaction"`
// DPoSV2EffectiveVotes defines the votes which producer will become a dposV2 effective node
DPoSV2EffectiveVotes common.Fixed64 `screw:"--dposv2effectivevotes" usage:"defines the minimum votes to active a DposV2 producer"`
// ExchangeVotes address of votes
@@ -646,6 +669,8 @@ type Configuration struct {
CRSchnorrStartHeight uint32 `screw:"--crschnorrstartheight" usage:"defines the start height to support CR related schnorr transaction"`
// VotesSchnorrStartHeight indicates the start height of votes related schnorr tx
VotesSchnorrStartHeight uint32 `screw:"--votesschnorrstartheight" usage:"defines the start height to support votes related schnorr transaction"`
+ // MultiExchangeVotesStartHeight indicates the start height of multi-addr exchange votes transaction
+ MultiExchangeVotesStartHeight uint32 `screw:"--multiexchangevotesstartheight" usage:"defines the start height to support multi-addr exchange votes transaction"`
// CrossChainMonitorStartHeight indicates the monitor height of cr cross chain arbitration
CrossChainMonitorStartHeight uint32 `screw:"--crosschainmonitorstartheight" usage:"defines the start height to monitor cr cross chain transaction"`
// CrossChainMonitorInterval indicates the interval value of cr cross chain arbitration
@@ -711,6 +736,12 @@ type DPoSConfiguration struct {
RevertToPOWNoBlockTime int64 `screw:"--reverttopownoblocktime" usage:"defines how long time does it take to revert to POW mode"`
// StopConfirmBlockTime defines how long time dose it take before stop confirm block.
StopConfirmBlockTime int64 `screw:"--stopconfirmblocktime" usage:"defines how long time does it take to stop confirm block"`
+ // RevertToPOWInterval defines how long time does it take to revert to POW mode.
+ RevertToPOWNoBlockTimeV1 int64 `screw:"--reverttopownoblocktimev1" usage:"defines how long time does it take to revert to POW mode"`
+ // StopConfirmBlockTime defines how long time dose it take before stop confirm block.
+ StopConfirmBlockTimeV1 int64 `screw:"--stopconfirmblocktimev1" usage:"defines how long time does it take to stop confirm block"`
+ // ChangeViewV1Height defines the height of ChangeView version 1.0
+ ChangeViewV1Height uint32 `screw:"--changeviewv1height" usage:"defines how the height of ChangeView version 1.0"`
// RevertToPOWStartHeight defines the start height to allow to revert to POW mode.
RevertToPOWStartHeight uint32 `screw:"--reverttopowstartheight" usage:"defines the start height to allow to revert to POW mode"`
// DPoSV2RewardAccumulateAddress defines the dposv2 reward accumulating address
@@ -730,6 +761,10 @@ type DPoSConfiguration struct {
SponsorsFilePath string `screw:"--sponsorsfilepath" usage:"defines the sponsors file path"`
// RecordSponsorStartHeight defines the start height to record sponsor.
RecordSponsorStartHeight uint32 `screw:"--recordsponsorstartheight" usage:"defines the start height to record sponsor"`
+ // NFTV2StartHeight defines the height of NFT 2.0 started, NFT transaction will record the detailed votes information.
+ NFTV2StartHeight uint32 `screw:"--NFTV2StartHeight" usage:"the start height of NFT 2.0 transaction"`
+ // DexStartHeight defines the height of DEX started.
+ DexStartHeight uint32 `screw:"--dexstartheight" usage:"the starting height of Dex support"`
}
type CRConfiguration struct {
@@ -900,9 +935,8 @@ func (p *Configuration) newRewardPerBlock(targetTimePerBlock time.Duration, heig
generatedBlocksPerYear := 365 * 24 * 60 * 60 / blockGenerateInterval
factor := uint32(1)
if height >= p.HalvingRewardHeight {
- factor = 2 + (height-p.HalvingRewardHeight)/p.HalvingRewardInterval
+ factor = 2 + (height-p.HalvingRewardHeight)/p.HalvingRewardInterval // HalvingRewardHeight: 1051200
}
-
return common.Fixed64(float64(newInflationPerYear) / float64(generatedBlocksPerYear) / math.Pow(2, float64(factor-1)))
}
diff --git a/core/checkpoint/manager.go b/core/checkpoint/manager.go
index b25c5d111..c9f70b0d3 100644
--- a/core/checkpoint/manager.go
+++ b/core/checkpoint/manager.go
@@ -88,6 +88,9 @@ type ICheckPoint interface {
// SavePeriod defines how long should we save the checkpoint.
SavePeriod() uint32
+ // SaveStartHeight returns the height to create checkpoints file.
+ SaveStartHeight() uint32
+
// EffectivePeriod defines the legal height a checkpoint can take
// effect.
EffectivePeriod() uint32
@@ -322,8 +325,6 @@ func (m *Manager) onBlockSaved(block *types.DposBlock,
filter func(point ICheckPoint) bool, async bool, isPow bool, revertToPowHeight uint32, init bool) {
sortedPoints := m.getOrderedCheckpoints()
- var saveCheckPoint bool
- var useCheckPoint bool
for _, v := range sortedPoints {
if filter != nil && !filter(v) {
@@ -333,7 +334,8 @@ func (m *Manager) onBlockSaved(block *types.DposBlock,
continue
}
v.OnBlockSaved(block)
- if !m.cfg.CheckPointConfiguration.NeedSave || init {
+
+ if !m.cfg.CheckPointConfiguration.NeedSave || init || block.Height <= v.SaveStartHeight() {
continue
}
@@ -344,30 +346,18 @@ func (m *Manager) onBlockSaved(block *types.DposBlock,
if !async {
<-reply
}
- } else if originalHeight > 0 &&
- (v.Key() != dposCheckpointKey && block.Height ==
- originalHeight+v.EffectivePeriod() ||
- v.Key() == dposCheckpointKey && useCheckPoint) {
+ } else if originalHeight > 0 && block.Height ==
+ originalHeight+v.EffectivePeriod() {
reply := make(chan bool, 1)
- if v.Key() == dposCheckpointKey || v.Key() == crCheckpointKey {
- m.channels[v.Key()].ReplaceRemove(v, reply, originalHeight)
- } else {
- m.channels[v.Key()].Replace(v, reply, originalHeight)
- }
+ m.channels[v.Key()].Replace(v, reply, originalHeight)
if !async {
<-reply
}
- if v.Key() == crCheckpointKey {
- useCheckPoint = true
- } else if v.Key() == dposCheckpointKey {
- useCheckPoint = false
- }
}
- if v.Key() != dposCheckpointKey && block.Height >=
- originalHeight+v.SavePeriod() ||
- v.Key() == dposCheckpointKey && saveCheckPoint || isPow {
+ if block.Height >=
+ originalHeight+v.SavePeriod() {
v.SetHeight(block.Height)
snapshot := v.Snapshot()
if snapshot == nil {
@@ -375,21 +365,10 @@ func (m *Manager) onBlockSaved(block *types.DposBlock,
continue
}
reply := make(chan bool, 1)
- if v.Key() == dposCheckpointKey || v.Key() == crCheckpointKey {
- if isPow && block.Height-revertToPowHeight > uint32(MaxCheckPointFilesCount) {
- m.channels[v.Key()].Remove(v, reply, block.Height-uint32(MaxCheckPointFilesCount))
- <-reply
- }
- }
m.channels[v.Key()].Save(snapshot, reply)
if !async {
<-reply
}
- if v.Key() == crCheckpointKey {
- saveCheckPoint = true
- } else if v.Key() == dposCheckpointKey {
- saveCheckPoint = false
- }
}
}
}
diff --git a/core/checkpoint/manager_test.go b/core/checkpoint/manager_test.go
index 3d52b634b..cfec3f09a 100644
--- a/core/checkpoint/manager_test.go
+++ b/core/checkpoint/manager_test.go
@@ -36,6 +36,10 @@ type checkpoint struct {
priority Priority
}
+func (c *checkpoint) SaveStartHeight() uint32 {
+ return 0
+}
+
func (c *checkpoint) StartHeight() uint32 {
return 0
}
diff --git a/core/contract/contract_test.go b/core/contract/contract_test.go
index 4c72f607d..beea2f1a4 100644
--- a/core/contract/contract_test.go
+++ b/core/contract/contract_test.go
@@ -7,14 +7,45 @@ package contract
import (
"encoding/hex"
+ "fmt"
"testing"
"github.com/elastos/Elastos.ELA/common"
"github.com/elastos/Elastos.ELA/crypto"
+ "github.com/elastos/Elastos.ELA/utils/test"
"github.com/stretchr/testify/assert"
)
+func TestCalculateDepositAddr(t *testing.T) {
+ test.SkipShort(t)
+ publicKeyStrs := make([]string, 0)
+ publicKeyStrs = append(publicKeyStrs, "0261056c3bb7fd2399a1e8e8ca00c9f213d9a9d8b5e986b75ee627ecdedbdadda1")
+ publicKeyStrs = append(publicKeyStrs, "039a6c4f6b0c679bb8023ccae91340b6489c79d482d07d42aba1d52a9e85bc29af")
+ publicKeyStrs = append(publicKeyStrs, "039fa77a2b64c3065023d6e0ef279dc87ffef7f634f28d5a58b707f2f6054385eb")
+ publicKeyStrs = append(publicKeyStrs, "02f7042c66d5da58a41677f52eaeba5dd776454c3df3cfb8e84484e249e0c689bc")
+
+ var publicKeys []*crypto.PublicKey
+ for _, publicKeyStr := range publicKeyStrs {
+ publicKeyBytes, _ := hex.DecodeString(publicKeyStr)
+ publicKey, _ := crypto.DecodePoint(publicKeyBytes)
+ publicKeys = append(publicKeys, publicKey)
+ }
+
+ multiCode, _ := CreateMultiSigRedeemScript(3, publicKeys)
+
+ ct, err := CreateDepositContractByCode(multiCode)
+ if err != nil {
+ fmt.Println("error:", err)
+ }
+ addr, err := ct.ToProgramHash().ToAddress()
+ if err != nil {
+ fmt.Println("error 2:", err)
+ }
+ fmt.Println("addr:", addr)
+
+}
+
func TestToProgramHash(t *testing.T) {
// Exit address
publicKeyHex := "022c9652d3ad5cc065aa9147dc2ad022f80001e8ed233de20f352950d351d472b7"
@@ -48,3 +79,52 @@ func TestToProgramHash(t *testing.T) {
t.FailNow()
}
}
+
+func TestBasicAlgorithm(t *testing.T) {
+ standardCodeStr := "2102cd62afdc81cde4b0a671991556e5b352e07d1c6ed0c95298618798f707f47b15ac"
+ standardCodeByte, _ := hex.DecodeString(standardCodeStr)
+ standardPubKey := common.GetPublicKeyFromCode(standardCodeByte)
+
+ //standard code hash
+ standardCodeHash, _ := PublicKeyToStandardCodeHash(standardPubKey)
+ fmt.Println("standardCodeHash", standardCodeHash)
+ ownerProgramHash, _ := PublicKeyToStandardProgramHash(standardPubKey)
+ fmt.Println("Code hash", ownerProgramHash.ToCodeHash())
+ assert.Equal(t, ownerProgramHash.ToCodeHash(), *standardCodeHash)
+
+ // standard stakeProgramHash
+ stakeProgramHash := common.Uint168FromCodeHash(
+ byte(PrefixDPoSV2), ownerProgramHash.ToCodeHash())
+ fmt.Println("stakeProgramHash", stakeProgramHash)
+ ct, _ := CreateStakeContractByCode(standardCodeByte)
+ stakeProgramHash2 := ct.ToProgramHash()
+ fmt.Println("stakeProgramHash2", stakeProgramHash2)
+ assert.Equal(t, *stakeProgramHash2, stakeProgramHash)
+
+ multiCodeStr := "522103424727948233d29f3186222a8cad449f34cb0de3f2122196344064a1dc44c4db2102a8097e33e19987d53df6e52c7a" +
+ "34516693c3179199b1889926be3c34029c98d92102cd62afdc81cde4b0a671991556e5b352e07d1c6ed0c95298618798f707f47b1553ae"
+ multiCodeByte, _ := hex.DecodeString(multiCodeStr)
+
+ //multicode programhash
+ ct, _ = CreateMultiSigContractByCode(multiCodeByte)
+ fmt.Println("multiCode hash", ct.ToCodeHash())
+ multiProgramHash := ct.ToProgramHash()
+ fmt.Println("multiCode ProgramHash", ct.ToProgramHash())
+ fmt.Println("multiCode ProgramHash2", common.ToProgramHash(byte(PrefixStandard), multiCodeByte))
+
+ //multicode code hash
+ codeHash1 := ct.ToProgramHash().ToCodeHash()
+ fmt.Println("multiCode ProgramHash", codeHash1)
+ codeHash2 := common.ToProgramHash(byte(PrefixStandard), multiCodeByte).ToCodeHash()
+ fmt.Println("multiCode ProgramHash2", codeHash2)
+ assert.Equal(t, codeHash1, codeHash2)
+
+ //multicode stake programhash
+ stakeProgramHash3 := common.Uint168FromCodeHash(
+ byte(PrefixDPoSV2), multiProgramHash.ToCodeHash())
+ fmt.Println("stakeProgramHash", stakeProgramHash)
+ ct, _ = CreateStakeContractByCode(multiCodeByte)
+ stakeProgramHash4 := ct.ToProgramHash()
+ fmt.Println("stakeProgramHash3", stakeProgramHash3)
+ assert.Equal(t, stakeProgramHash3, *stakeProgramHash4)
+}
diff --git a/core/transaction/activateproducertransaction.go b/core/transaction/activateproducertransaction.go
index ef26d77e6..42f6ac206 100644
--- a/core/transaction/activateproducertransaction.go
+++ b/core/transaction/activateproducertransaction.go
@@ -12,7 +12,6 @@ import (
"math"
"github.com/elastos/Elastos.ELA/common"
- "github.com/elastos/Elastos.ELA/core/contract"
common2 "github.com/elastos/Elastos.ELA/core/types/common"
"github.com/elastos/Elastos.ELA/core/types/payload"
crstate "github.com/elastos/Elastos.ELA/cr/state"
@@ -158,8 +157,7 @@ func (t *ActivateProducerTransaction) SpecialContextCheck() (elaerr.ELAError, bo
depositAmount := common.Fixed64(0)
if t.parameters.BlockHeight < t.parameters.Config.CRConfiguration.CRVotingStartHeight {
- programHash, err := contract.PublicKeyToDepositProgramHash(
- producer.OwnerPublicKey())
+ programHash, err := state.GetOwnerKeyDepositProgramHash(producer.OwnerPublicKey())
if err != nil {
return elaerr.Simple(elaerr.ErrTxPayload, err), true
}
diff --git a/core/transaction/activateproducertransaction_test.go b/core/transaction/activateproducertransaction_test.go
index 05ae77917..f63d39610 100644
--- a/core/transaction/activateproducertransaction_test.go
+++ b/core/transaction/activateproducertransaction_test.go
@@ -78,12 +78,12 @@ func (s *txValidatorTestSuite) TestCheckActivateProducerTransaction() {
{
registerPayload := &payload.ProducerInfo{
- OwnerPublicKey: publicKey1,
- NodePublicKey: publicKey1,
- NickName: "",
- Url: "",
- Location: 1,
- NetAddress: "",
+ OwnerKey: publicKey1,
+ NodePublicKey: publicKey1,
+ NickName: "",
+ Url: "",
+ Location: 1,
+ NetAddress: "",
}
programs = []*program.Program{{
Code: getCodeByPubKeyStr(publicKeyStr1),
@@ -159,13 +159,13 @@ func (s *txValidatorTestSuite) TestCheckActivateProducerTransaction() {
{
registerPayload := &payload.ProducerInfo{
- OwnerPublicKey: publicKey1,
- NodePublicKey: publicKey1,
- NickName: "",
- Url: "",
- Location: 1,
- NetAddress: "",
- StakeUntil: 100,
+ OwnerKey: publicKey1,
+ NodePublicKey: publicKey1,
+ NickName: "",
+ Url: "",
+ Location: 1,
+ NetAddress: "",
+ StakeUntil: 100,
}
programs = []*program.Program{{
Code: getCodeByPubKeyStr(publicKeyStr1),
diff --git a/core/transaction/cancelproducertransaction.go b/core/transaction/cancelproducertransaction.go
index 2fe9a297e..b9e079394 100644
--- a/core/transaction/cancelproducertransaction.go
+++ b/core/transaction/cancelproducertransaction.go
@@ -8,6 +8,7 @@ package transaction
import (
"bytes"
"errors"
+ "fmt"
"github.com/elastos/Elastos.ELA/core/contract"
"github.com/elastos/Elastos.ELA/core/types/interfaces"
@@ -34,6 +35,20 @@ func (t *CancelProducerTransaction) IsAllowedInPOWConsensus() bool {
return false
}
+func (t *CancelProducerTransaction) HeightVersionCheck() error {
+ blockHeight := t.parameters.BlockHeight
+ chainParams := t.parameters.Config
+
+ if blockHeight < chainParams.SupportMultiCodeHeight {
+ if t.PayloadVersion() == payload.ProcessMultiCodeVersion {
+ return errors.New(fmt.Sprintf("not support %s transaction "+
+ "with payload version %d before SupportMultiCodeHeight",
+ t.TxType().Name(), t.PayloadVersion()))
+ }
+ }
+ return nil
+}
+
func (t *CancelProducerTransaction) SpecialContextCheck() (elaerr.ELAError, bool) {
producer, err := t.checkProcessProducer(t.parameters, t)
if err != nil {
@@ -66,12 +81,11 @@ func (t *CancelProducerTransaction) checkProcessProducer(params *TransactionPara
}
// check signature
- publicKey, err := crypto.DecodePoint(processProducer.OwnerPublicKey)
- if err != nil {
- return nil, errors.New("invalid public key in payload")
- }
-
- if t.PayloadVersion() != payload.ProcessProducerSchnorrVersion {
+ if t.PayloadVersion() == payload.ProcessProducerVersion {
+ publicKey, err := crypto.DecodePoint(processProducer.OwnerKey)
+ if err != nil {
+ return nil, errors.New("invalid public key in payload")
+ }
signedBuf := new(bytes.Buffer)
err = processProducer.SerializeUnsigned(signedBuf, t.PayloadVersion())
if err != nil {
@@ -81,19 +95,24 @@ func (t *CancelProducerTransaction) checkProcessProducer(params *TransactionPara
if err != nil {
return nil, errors.New("invalid signature in payload")
}
- } else {
+ } else if t.PayloadVersion() == payload.ProcessProducerSchnorrVersion {
if !contract.IsSchnorr(t.Programs()[0].Code) {
return nil, errors.New("only schnorr code can use ProcessProducerSchnorrVersion")
}
pk := t.Programs()[0].Code[2:]
- if !bytes.Equal(pk, processProducer.OwnerPublicKey) {
- return nil, errors.New("tx program pk must equal with processProducer OwnerPublicKey ")
+ if !bytes.Equal(pk, processProducer.OwnerKey) {
+ return nil, errors.New("tx program pk must equal with processProducer OwnerKey ")
+ }
+ } else if t.PayloadVersion() == payload.ProcessMultiCodeVersion {
+ if !contract.IsMultiSig(t.Programs()[0].Code) {
+ return nil, elaerr.Simple(elaerr.ErrTxPayload,
+ errors.New("only multi sign code can use ProcessMultiCodeVersion"))
}
}
- producer := t.parameters.BlockChain.GetState().GetProducer(processProducer.OwnerPublicKey)
+ producer := t.parameters.BlockChain.GetState().GetProducer(processProducer.OwnerKey)
if producer == nil || !bytes.Equal(producer.OwnerPublicKey(),
- processProducer.OwnerPublicKey) {
+ processProducer.OwnerKey) {
return nil, errors.New("getting unknown producer")
}
return producer, nil
diff --git a/core/transaction/cancelproducertransaction_test.go b/core/transaction/cancelproducertransaction_test.go
index 6806af9c4..225215aa3 100644
--- a/core/transaction/cancelproducertransaction_test.go
+++ b/core/transaction/cancelproducertransaction_test.go
@@ -28,7 +28,7 @@ func (s *txValidatorTestSuite) TestCheckCancelProducerTransaction() {
errPublicKey, _ := common.HexStringToBytes(errPublicKeyStr)
cancelPayload := &payload.ProcessProducer{
- OwnerPublicKey: publicKey1,
+ OwnerKey: publicKey1,
}
programs := []*program.Program{{
@@ -48,17 +48,17 @@ func (s *txValidatorTestSuite) TestCheckCancelProducerTransaction() {
programs,
)
- cancelPayload.OwnerPublicKey = errPublicKey
+ cancelPayload.OwnerKey = errPublicKey
txn = CreateTransactionByType(txn, s.Chain)
err, _ := txn.SpecialContextCheck()
s.EqualError(err, "transaction validate error: payload content invalid:invalid public key in payload")
- cancelPayload.OwnerPublicKey = publicKey2
+ cancelPayload.OwnerKey = publicKey2
err, _ = txn.SpecialContextCheck()
s.EqualError(err, "transaction validate error: payload content invalid:invalid signature in payload")
buf := new(bytes.Buffer)
- cancelPayload.OwnerPublicKey = publicKey1
+ cancelPayload.OwnerKey = publicKey1
cancelPayload.SerializeUnsigned(buf, 0)
sig, _ := crypto.Sign(privateKey1, buf.Bytes())
@@ -81,12 +81,12 @@ func (s *txValidatorTestSuite) TestCheckCancelProducerTransaction() {
{
registerPayload := &payload.ProducerInfo{
- OwnerPublicKey: publicKey1,
- NodePublicKey: publicKey1,
- NickName: "",
- Url: "",
- Location: 1,
- NetAddress: "",
+ OwnerKey: publicKey1,
+ NodePublicKey: publicKey1,
+ NickName: "",
+ Url: "",
+ Location: 1,
+ NetAddress: "",
}
programs = []*program.Program{{
Code: getCodeByPubKeyStr(publicKeyStr1),
@@ -142,13 +142,13 @@ func (s *txValidatorTestSuite) TestCheckCancelProducerTransaction() {
{
registerPayload := &payload.ProducerInfo{
- OwnerPublicKey: publicKey1,
- NodePublicKey: publicKey1,
- NickName: "",
- Url: "",
- Location: 1,
- NetAddress: "",
- StakeUntil: 100,
+ OwnerKey: publicKey1,
+ NodePublicKey: publicKey1,
+ NickName: "",
+ Url: "",
+ Location: 1,
+ NetAddress: "",
+ StakeUntil: 100,
}
programs = []*program.Program{{
Code: getCodeByPubKeyStr(publicKeyStr1),
@@ -204,12 +204,12 @@ func (s *txValidatorTestSuite) TestCheckCancelProducerTransaction() {
{
registerPayload := &payload.ProducerInfo{
- OwnerPublicKey: publicKey1,
- NodePublicKey: publicKey1,
- NickName: "",
- Url: "",
- Location: 1,
- NetAddress: "",
+ OwnerKey: publicKey1,
+ NodePublicKey: publicKey1,
+ NickName: "",
+ Url: "",
+ Location: 1,
+ NetAddress: "",
}
programs = []*program.Program{{
Code: getCodeByPubKeyStr(publicKeyStr1),
@@ -271,13 +271,13 @@ func (s *txValidatorTestSuite) TestCheckCancelProducerTransaction() {
programs,
)
updatePayload := &payload.ProducerInfo{
- OwnerPublicKey: publicKey1,
- NodePublicKey: publicKey1,
- NickName: "nick name",
- Url: "www.elastos.org",
- Location: 2,
- NetAddress: "",
- StakeUntil: 10,
+ OwnerKey: publicKey1,
+ NodePublicKey: publicKey1,
+ NickName: "nick name",
+ Url: "www.elastos.org",
+ Location: 2,
+ NetAddress: "",
+ StakeUntil: 10,
}
txn2.SetPayload(updatePayload)
diff --git a/core/transaction/crcproposaltrackingtransaction.go b/core/transaction/crcproposaltrackingtransaction.go
index d00939652..a8db3e020 100644
--- a/core/transaction/crcproposaltrackingtransaction.go
+++ b/core/transaction/crcproposaltrackingtransaction.go
@@ -156,17 +156,17 @@ func (t *CRCProposalTrackingTransaction) normalCheckCRCProposalTrackingSignature
params *TransactionParameters, cptPayload *payload.CRCProposalTracking, pState *crstate.ProposalState,
payloadVersion byte) error {
// Check new owner public key.
- if len(cptPayload.NewOwnerPublicKey) != 0 {
- return errors.New("the NewOwnerPublicKey need to be empty")
+ if len(cptPayload.NewOwnerKey) != 0 {
+ return errors.New("the NewOwnerKey need to be empty")
}
// Check signature of proposal owner.
- if !bytes.Equal(pState.ProposalOwner, cptPayload.OwnerPublicKey) {
- return errors.New("the OwnerPublicKey is not owner of proposal")
+ if !bytes.Equal(pState.ProposalOwner, cptPayload.OwnerKey) {
+ return errors.New("the OwnerKey is not owner of proposal")
}
signedBuf := new(bytes.Buffer)
if err := checkProposalOwnerSignature(cptPayload,
- cptPayload.OwnerPublicKey, signedBuf, payloadVersion); err != nil {
+ cptPayload.OwnerKey, signedBuf, payloadVersion); err != nil {
return err
}
@@ -324,7 +324,7 @@ func (t *CRCProposalTrackingTransaction) checkCRCProposalOwnerTracking(
}
// Check new owner public.
- if bytes.Equal(pState.ProposalOwner, cptPayload.NewOwnerPublicKey) {
+ if bytes.Equal(pState.ProposalOwner, cptPayload.NewOwnerKey) {
return errors.New("invalid new owner public key")
}
@@ -336,18 +336,18 @@ func (t *CRCProposalTrackingTransaction) checkCRCProposalTrackingSignature(
params *TransactionParameters, cptPayload *payload.CRCProposalTracking, pState *crstate.ProposalState,
payloadVersion byte) error {
// Check signature of proposal owner.
- if !bytes.Equal(pState.ProposalOwner, cptPayload.OwnerPublicKey) {
- return errors.New("the OwnerPublicKey is not owner of proposal")
+ if !bytes.Equal(pState.ProposalOwner, cptPayload.OwnerKey) {
+ return errors.New("the OwnerKey is not owner of proposal")
}
signedBuf := new(bytes.Buffer)
if err := checkProposalOwnerSignature(cptPayload,
- cptPayload.OwnerPublicKey, signedBuf, payloadVersion); err != nil {
+ cptPayload.OwnerKey, signedBuf, payloadVersion); err != nil {
return err
}
// Check other new owner signature.
if err := checkProposalNewOwnerSignature(cptPayload,
- cptPayload.NewOwnerPublicKey, signedBuf); err != nil {
+ cptPayload.NewOwnerKey, signedBuf); err != nil {
return err
}
diff --git a/core/transaction/crcproposaltrackingtransaction_test.go b/core/transaction/crcproposaltrackingtransaction_test.go
index 7196b6031..8f7ea5efe 100644
--- a/core/transaction/crcproposaltrackingtransaction_test.go
+++ b/core/transaction/crcproposaltrackingtransaction_test.go
@@ -38,7 +38,7 @@ func (s *txValidatorTestSuite) TestCheckCRCProposalTrackingTransaction() {
pld := payload.CRCProposal{
ProposalType: 0,
- OwnerPublicKey: ownerPubKey,
+ OwnerKey: ownerPubKey,
CRCouncilMemberDID: *randomUint168(),
DraftHash: *randomUint256(),
Budgets: createBudgets(3),
@@ -88,7 +88,7 @@ func (s *txValidatorTestSuite) TestCheckCRCProposalTrackingTransaction() {
BlockChain: s.Chain,
})
err, _ = txn.SpecialContextCheck()
- s.EqualError(err, "transaction validate error: payload content invalid:the NewOwnerPublicKey need to be empty")
+ s.EqualError(err, "transaction validate error: payload content invalid:the NewOwnerKey need to be empty")
// Check Progress tracking tx.
txn = s.getCRCProposalTrackingTx(payload.Progress, *proposalHash, 1,
@@ -117,7 +117,7 @@ func (s *txValidatorTestSuite) TestCheckCRCProposalTrackingTransaction() {
BlockChain: s.Chain,
})
err, _ = txn.SpecialContextCheck()
- s.EqualError(err, "transaction validate error: payload content invalid:the NewOwnerPublicKey need to be empty")
+ s.EqualError(err, "transaction validate error: payload content invalid:the NewOwnerKey need to be empty")
// Check Terminated tracking tx.
txn = s.getCRCProposalTrackingTx(payload.Terminated, *proposalHash, 0,
@@ -160,7 +160,7 @@ func (s *txValidatorTestSuite) TestCheckCRCProposalTrackingTransaction() {
BlockChain: s.Chain,
})
err, _ = txn.SpecialContextCheck()
- s.EqualError(err, "transaction validate error: payload content invalid:the NewOwnerPublicKey need to be empty")
+ s.EqualError(err, "transaction validate error: payload content invalid:the NewOwnerKey need to be empty")
// Check ChangeOwner tracking tx.
txn = s.getCRCProposalTrackingTx(payload.ChangeOwner, *proposalHash, 0,
@@ -227,7 +227,7 @@ func (s *txValidatorTestSuite) TestCheckCRCProposalTrackingTransaction() {
// Check proposal status is not VoterAgreed.
pld = payload.CRCProposal{
ProposalType: 0,
- OwnerPublicKey: ownerPubKey,
+ OwnerKey: ownerPubKey,
CRCouncilMemberDID: *randomUint168(),
DraftHash: *randomUint256(),
Budgets: createBudgets(3),
@@ -255,7 +255,7 @@ func (s *txValidatorTestSuite) TestCheckCRCProposalTrackingTransaction() {
// Check reach max proposal tracking count.
pld = payload.CRCProposal{
ProposalType: 0,
- OwnerPublicKey: ownerPubKey,
+ OwnerKey: ownerPubKey,
CRCouncilMemberDID: *randomUint168(),
DraftHash: *randomUint256(),
Budgets: createBudgets(3),
@@ -316,8 +316,8 @@ func (s *txValidatorTestSuite) getCRCProposalTrackingTx(
ProposalHash: proposalHash,
Stage: stage,
MessageHash: common.Hash(documentData),
- OwnerPublicKey: ownerPublicKey,
- NewOwnerPublicKey: newownerpublickey,
+ OwnerKey: ownerPublicKey,
+ NewOwnerKey: newownerpublickey,
SecretaryGeneralOpinionHash: common.Hash(opinionHash),
}
diff --git a/core/transaction/crcproposaltransaction.go b/core/transaction/crcproposaltransaction.go
index 9c8667ce2..94f179c10 100644
--- a/core/transaction/crcproposaltransaction.go
+++ b/core/transaction/crcproposaltransaction.go
@@ -182,15 +182,15 @@ func (t *CRCProposalTransaction) checkChangeProposalOwner(params *TransactionPar
return errors.New("proposal status is not VoterAgreed")
}
- if _, err := crypto.DecodePoint(proposal.OwnerPublicKey); err != nil {
+ if _, err := crypto.DecodePoint(proposal.OwnerKey); err != nil {
return errors.New("invalid owner public key")
}
- if _, err := crypto.DecodePoint(proposal.NewOwnerPublicKey); err != nil {
+ if _, err := crypto.DecodePoint(proposal.NewOwnerKey); err != nil {
return errors.New("invalid new owner public key")
}
- if bytes.Equal(proposal.NewOwnerPublicKey, proposalState.ProposalOwner) &&
+ if bytes.Equal(proposal.NewOwnerKey, proposalState.ProposalOwner) &&
proposal.NewRecipient.IsEqual(proposalState.Recipient) {
return errors.New("new owner or recipient must be different from the previous one")
}
@@ -211,7 +211,7 @@ func (t *CRCProposalTransaction) checkChangeOwnerSign(proposal *payload.CRCPropo
}
// Check signature of owner.
- publicKey, err := crypto.DecodePoint(proposal.OwnerPublicKey)
+ publicKey, err := crypto.DecodePoint(proposal.OwnerKey)
if err != nil {
return errors.New("invalid owner")
}
@@ -225,7 +225,7 @@ func (t *CRCProposalTransaction) checkChangeOwnerSign(proposal *payload.CRCPropo
}
// Check signature of new owner.
- newOwnerPublicKey, err := crypto.DecodePoint(proposal.NewOwnerPublicKey)
+ newOwnerPublicKey, err := crypto.DecodePoint(proposal.NewOwnerKey)
if err != nil {
return errors.New("invalid owner")
}
@@ -258,9 +258,9 @@ func (t *CRCProposalTransaction) checkChangeOwnerSign(proposal *payload.CRCPropo
}
func (t *CRCProposalTransaction) checkCloseProposal(params *TransactionParameters, proposal *payload.CRCProposal, PayloadVersion byte) error {
- _, err := crypto.DecodePoint(proposal.OwnerPublicKey)
+ _, err := crypto.DecodePoint(proposal.OwnerKey)
if err != nil {
- return errors.New("DecodePoint from OwnerPublicKey error")
+ return errors.New("DecodePoint from OwnerKey error")
}
if ps := t.parameters.BlockChain.GetCRCommittee().GetProposal(proposal.TargetProposalHash); ps == nil {
return errors.New("CloseProposalHash does not exist")
@@ -284,7 +284,7 @@ func (t *CRCProposalTransaction) checkCloseProposal(params *TransactionParameter
func (t *CRCProposalTransaction) checkOwnerAndCRCouncilMemberSign(proposal *payload.CRCProposal, crMemberCode []byte,
PayloadVersion byte) error {
// Check signature of owner.
- publicKey, err := crypto.DecodePoint(proposal.OwnerPublicKey)
+ publicKey, err := crypto.DecodePoint(proposal.OwnerKey)
if err != nil {
return errors.New("invalid owner")
}
@@ -322,7 +322,7 @@ func (t *CRCProposalTransaction) checkChangeSecretaryGeneralProposalTx(params *T
return errors.New("SecretaryGeneral NodePublicKey and DID is not matching")
}
// Check owner public key
- if _, err := crypto.DecodePoint(crcProposal.OwnerPublicKey); err != nil {
+ if _, err := crypto.DecodePoint(crcProposal.OwnerKey); err != nil {
return errors.New("invalid owner public key")
}
@@ -387,7 +387,7 @@ func checkProposalOwnerSign(crcProposal *payload.CRCProposal, signedBuf *bytes.B
//get ownerCode
var code []byte
var err error
- if code, err = getCode(crcProposal.OwnerPublicKey); err != nil {
+ if code, err = getCode(crcProposal.OwnerKey); err != nil {
return err
}
// get verify data
@@ -442,9 +442,9 @@ func (t *CRCProposalTransaction) checkReservedCustomID(params *TransactionParame
if t.parameters.BlockChain.GetCRCommittee().GetProposalManager().ReservedCustomID {
return errors.New("Already have one ReservedCustomID proposal")
}
- _, err := crypto.DecodePoint(proposal.OwnerPublicKey)
+ _, err := crypto.DecodePoint(proposal.OwnerKey)
if err != nil {
- return errors.New("DecodePoint from OwnerPublicKey error")
+ return errors.New("DecodePoint from OwnerKey error")
}
if len(proposal.ReservedCustomIDList) == 0 {
@@ -471,9 +471,9 @@ func (t *CRCProposalTransaction) checkReservedCustomID(params *TransactionParame
}
func (t *CRCProposalTransaction) checkReceivedCustomID(params *TransactionParameters, proposal *payload.CRCProposal, PayloadVersion byte) error {
- _, err := crypto.DecodePoint(proposal.OwnerPublicKey)
+ _, err := crypto.DecodePoint(proposal.OwnerKey)
if err != nil {
- return errors.New("DecodePoint from OwnerPublicKey error")
+ return errors.New("DecodePoint from OwnerKey error")
}
reservedCustomIDList := t.parameters.BlockChain.GetCRCommittee().GetReservedCustomIDLists()
receivedCustomIDList := t.parameters.BlockChain.GetCRCommittee().GetReceivedCustomIDLists()
@@ -510,9 +510,9 @@ func (t *CRCProposalTransaction) checkReceivedCustomID(params *TransactionParame
}
func (t *CRCProposalTransaction) checkChangeCustomIDFee(params *TransactionParameters, proposal *payload.CRCProposal, PayloadVersion byte) error {
- _, err := crypto.DecodePoint(proposal.OwnerPublicKey)
+ _, err := crypto.DecodePoint(proposal.OwnerKey)
if err != nil {
- return errors.New("DecodePoint from OwnerPublicKey error")
+ return errors.New("DecodePoint from OwnerKey error")
}
if proposal.RateOfCustomIDFee < 0 {
return errors.New("invalid fee rate of custom ID")
@@ -528,9 +528,9 @@ func (t *CRCProposalTransaction) checkChangeCustomIDFee(params *TransactionParam
}
func (t *CRCProposalTransaction) checkRegisterSideChainProposal(params *TransactionParameters, proposal *payload.CRCProposal, payloadVersion byte) error {
- _, err := crypto.DecodePoint(proposal.OwnerPublicKey)
+ _, err := crypto.DecodePoint(proposal.OwnerKey)
if err != nil {
- return errors.New("DecodePoint from OwnerPublicKey error")
+ return errors.New("DecodePoint from OwnerKey error")
}
if proposal.SideChainName == "" {
diff --git a/core/transaction/crcproposaltransaction_test.go b/core/transaction/crcproposaltransaction_test.go
index 3b086d517..cd7cd0c14 100644
--- a/core/transaction/crcproposaltransaction_test.go
+++ b/core/transaction/crcproposaltransaction_test.go
@@ -141,7 +141,7 @@ func (s *txValidatorTestSuite) getSecretaryGeneralCRCProposalTx(ownerPublicKeySt
crcProposalPayload := &payload.CRCProposal{
ProposalType: payload.SecretaryGeneral,
CategoryData: "111",
- OwnerPublicKey: ownerPublicKey,
+ OwnerKey: ownerPublicKey,
DraftHash: common.Hash(draftData),
SecretaryGeneralPublicKey: secretaryPublicKey,
SecretaryGeneralDID: *secretaryGeneralDID,
@@ -269,7 +269,7 @@ func (s *txValidatorTestSuite) getCRCRegisterSideChainProposalTx(publicKeyStr, p
CRCouncilMemberDID, _ := blockchain.GetDIDFromCode(getCodeByPubKeyStr(crPublicKeyStr))
crcProposalPayload := &payload.CRCProposal{
ProposalType: payload.RegisterSideChain,
- OwnerPublicKey: normalPublicKey,
+ OwnerKey: normalPublicKey,
CRCouncilMemberDID: *CRCouncilMemberDID,
DraftHash: common.Hash(draftData),
SideChainInfo: payload.SideChainInfo{
@@ -427,7 +427,7 @@ func (s *txValidatorTestSuite) TestCheckCRCProposalTransaction() {
// invalid owner
txn = s.getCRCProposalTx(publicKeyStr2, privateKeyStr2, publicKeyStr1, privateKeyStr1)
- txn.Payload().(*payload.CRCProposal).OwnerPublicKey = []byte{}
+ txn.Payload().(*payload.CRCProposal).OwnerKey = []byte{}
txn = CreateTransactionByType(txn, s.Chain)
txn.SetParameters(&TransactionParameters{
Transaction: txn,
@@ -443,7 +443,7 @@ func (s *txValidatorTestSuite) TestCheckCRCProposalTransaction() {
// invalid owner signature
txn = s.getCRCProposalTx(publicKeyStr2, privateKeyStr2, publicKeyStr1, privateKeyStr1)
publicKey1, _ := common.HexStringToBytes(publicKeyStr1)
- txn.Payload().(*payload.CRCProposal).OwnerPublicKey = publicKey1
+ txn.Payload().(*payload.CRCProposal).OwnerKey = publicKey1
txn = CreateTransactionByType(txn, s.Chain)
txn.SetParameters(&TransactionParameters{
Transaction: txn,
@@ -499,7 +499,7 @@ func (s *txValidatorTestSuite) TestCheckCRCProposalTransaction() {
proposalState2, proposal2 := s.createSpecificStatusProposal(publicKey1, publicKey2, tenureHeight+1,
crstate.VoterAgreed, payload.ChangeProposalOwner)
proposal2.TargetProposalHash = targetHash
- proposal2.OwnerPublicKey = newOwnerPublicKey
+ proposal2.OwnerKey = newOwnerPublicKey
s.Chain.GetCRCommittee().GetProposalManager().Proposals[targetHash] = proposalState2
txn = s.getCRChangeProposalOwnerProposalTx(publicKeyStr2, privateKeyStr2, publicKeyStr1, privateKeyStr1,
newOwnerPublicKeyStr, targetHash)
@@ -668,7 +668,7 @@ func (s *txValidatorTestSuite) getCRCProposalTx(publicKeyStr, privateKeyStr,
did2, _ := blockchain.GetDIDFromCode(code2)
crcProposalPayload := &payload.CRCProposal{
ProposalType: payload.Normal,
- OwnerPublicKey: publicKey1,
+ OwnerKey: publicKey1,
CRCouncilMemberDID: *did2,
DraftHash: common.Hash(draftData),
Budgets: createBudgets(3),
@@ -717,8 +717,8 @@ func (s *txValidatorTestSuite) getCRChangeProposalOwnerProposalTx(publicKeyStr,
crcProposalPayload := &payload.CRCProposal{
ProposalType: payload.ChangeProposalOwner,
- OwnerPublicKey: crPublicKey,
- NewOwnerPublicKey: newOwnerPublicKey,
+ OwnerKey: crPublicKey,
+ NewOwnerKey: newOwnerPublicKey,
TargetProposalHash: targetHash,
DraftHash: common.Hash(draftData),
CRCouncilMemberDID: *crDid,
@@ -751,7 +751,7 @@ func (s *txValidatorTestSuite) createSpecificStatusProposal(publicKey1, publicKe
CRCouncilMemberDID, _ := blockchain.GetDIDFromCode(code2)
proposal := &payload.CRCProposal{
ProposalType: proposalType,
- OwnerPublicKey: publicKey1,
+ OwnerKey: publicKey1,
CRCouncilMemberDID: *CRCouncilMemberDID,
DraftHash: common.Hash(draftData),
Budgets: createBudgets(3),
@@ -779,7 +779,7 @@ func (s *txValidatorTestSuite) createSpecificStatusProposal(publicKey1, publicKe
FinalPaymentStatus: false,
TrackingCount: 0,
TerminatedHeight: 0,
- ProposalOwner: proposal.OwnerPublicKey,
+ ProposalOwner: proposal.OwnerKey,
}
return proposalState, proposal
}
@@ -811,7 +811,7 @@ func (s *txValidatorTestSuite) getCRCCloseProposalTxWithHash(publicKeyStr, priva
CRCouncilMemberDID, _ := blockchain.GetDIDFromCode(code2)
crcProposalPayload := &payload.CRCProposal{
ProposalType: payload.CloseProposal,
- OwnerPublicKey: publicKey1,
+ OwnerKey: publicKey1,
CRCouncilMemberDID: *CRCouncilMemberDID,
DraftHash: common.Hash(draftData),
TargetProposalHash: closeProposalHash,
@@ -862,7 +862,7 @@ func (s *txValidatorTestSuite) getCRCCloseProposalTx(publicKeyStr, privateKeyStr
CRCouncilMemberDID, _ := blockchain.GetDIDFromCode(code2)
crcProposalPayload := &payload.CRCProposal{
ProposalType: payload.CloseProposal,
- OwnerPublicKey: publicKey2,
+ OwnerKey: publicKey2,
CRCouncilMemberDID: *CRCouncilMemberDID,
DraftHash: common.Hash(draftData),
TargetProposalHash: common.Hash(randomBytes(10)),
@@ -913,7 +913,7 @@ func (s *txValidatorTestSuite) getCRCReservedCustomIDProposalTx(publicKeyStr, pr
CRCouncilMemberDID, _ := blockchain.GetDIDFromCode(code2)
crcProposalPayload := &payload.CRCProposal{
ProposalType: payload.ReserveCustomID,
- OwnerPublicKey: publicKey2,
+ OwnerKey: publicKey2,
CRCouncilMemberDID: *CRCouncilMemberDID,
DraftHash: common.Hash(draftData),
ReservedCustomIDList: []string{randomName(3), randomName(3), randomName(3)},
diff --git a/core/transaction/crcproposalwithdraw.go b/core/transaction/crcproposalwithdraw.go
index 4eb022bae..e346d7bc4 100644
--- a/core/transaction/crcproposalwithdraw.go
+++ b/core/transaction/crcproposalwithdraw.go
@@ -122,8 +122,8 @@ func (t *CRCProposalWithdrawTransaction) SpecialContextCheck() (result elaerr.EL
"Finished, Aborted or Terminated")), true
}
- if !bytes.Equal(proposalState.ProposalOwner, withdrawPayload.OwnerPublicKey) {
- return elaerr.Simple(elaerr.ErrTxPayload, errors.New("the OwnerPublicKey is not owner of proposal")), true
+ if !bytes.Equal(proposalState.ProposalOwner, withdrawPayload.OwnerKey) {
+ return elaerr.Simple(elaerr.ErrTxPayload, errors.New("the OwnerKey is not owner of proposal")), true
}
fee := getTransactionFee(t, t.references)
if t.isSmallThanMinTransactionFee(fee) {
@@ -174,7 +174,7 @@ func (t *CRCProposalWithdrawTransaction) SpecialContextCheck() (result elaerr.EL
return elaerr.Simple(elaerr.ErrTxPayload, err), true
}
var code []byte
- if code, err = getCode(withdrawPayload.OwnerPublicKey); err != nil {
+ if code, err = getCode(withdrawPayload.OwnerKey); err != nil {
return elaerr.Simple(elaerr.ErrTxPayload, err), true
}
err = blockchain.CheckCRTransactionSignature(withdrawPayload.Signature, code, signedBuf.Bytes())
diff --git a/core/transaction/crcproposalwithdraw_test.go b/core/transaction/crcproposalwithdraw_test.go
index fec8a89ab..66f6ee593 100644
--- a/core/transaction/crcproposalwithdraw_test.go
+++ b/core/transaction/crcproposalwithdraw_test.go
@@ -60,9 +60,9 @@ func (s *txValidatorTestSuite) TestCheckCRCProposalWithdrawTransaction() {
Recipient, CRExpensesAddressU168, 9*ela, 50*ela, 0)
crcProposalWithdraw, _ := txn.Payload().(*payload.CRCProposalWithdraw)
pld := payload.CRCProposal{
- OwnerPublicKey: pk1Bytes,
- Recipient: *Recipient,
- Budgets: createBudgets(3),
+ OwnerKey: pk1Bytes,
+ Recipient: *Recipient,
+ Budgets: createBudgets(3),
}
propState := &crstate.ProposalState{
Status: crstate.VoterAgreed,
@@ -147,7 +147,7 @@ func (s *txValidatorTestSuite) TestCheckCRCProposalWithdrawTransaction() {
propState.ProposalOwner = pk2Bytes
err, _ = txn.SpecialContextCheck()
- s.EqualError(err, "transaction validate error: payload content invalid:the OwnerPublicKey is not owner of proposal")
+ s.EqualError(err, "transaction validate error: payload content invalid:the OwnerKey is not owner of proposal")
references[inputs[0]] = *outputs[1]
txn.SetReferences(references)
@@ -247,15 +247,15 @@ func (s *txValidatorTestSuite) getCRCProposalWithdrawTx(crPublicKeyStr,
switch payloadVersion {
case 0x00:
crcProposalWithdraw = &payload.CRCProposalWithdraw{
- ProposalHash: *randomUint256(),
- OwnerPublicKey: pkBytes,
+ ProposalHash: *randomUint256(),
+ OwnerKey: pkBytes,
}
case 0x01:
crcProposalWithdraw = &payload.CRCProposalWithdraw{
- ProposalHash: *randomUint256(),
- OwnerPublicKey: pkBytes,
- Recipient: *recipient,
- Amount: recipAmout,
+ ProposalHash: *randomUint256(),
+ OwnerKey: pkBytes,
+ Recipient: *recipient,
+ Amount: recipAmout,
}
txn.SetPayloadVersion(payload.CRCProposalWithdrawVersion01)
}
diff --git a/core/transaction/createnfttransaction.go b/core/transaction/createnfttransaction.go
index c8f2cf2df..30d49fced 100644
--- a/core/transaction/createnfttransaction.go
+++ b/core/transaction/createnfttransaction.go
@@ -6,6 +6,7 @@
package transaction
import (
+ "bytes"
"errors"
"fmt"
"github.com/elastos/Elastos.ELA/common"
@@ -70,6 +71,17 @@ func (t *CreateNFTTransaction) HeightVersionCheck() error {
return errors.New(fmt.Sprintf("not support %s transaction "+
"before NFTStartHeight", t.TxType().Name()))
}
+ if blockHeight < chainParams.DPoSConfiguration.NFTV2StartHeight &&
+ t.payloadVersion >= payload.CreateNFTVersion2 {
+ return errors.New(fmt.Sprintf("not support %s transaction "+
+ "before NFTV2StartHeight", t.TxType().Name()))
+ }
+ if blockHeight >= chainParams.DPoSConfiguration.NFTV2StartHeight &&
+ t.payloadVersion != payload.CreateNFTVersion2 {
+ return errors.New(fmt.Sprintf("not support %s transaction "+
+ "with payload version 0 after NFTV2StartHeight", t.TxType().Name()))
+ }
+
return nil
}
@@ -86,6 +98,7 @@ func (t *CreateNFTTransaction) SpecialContextCheck() (elaerr.ELAError, bool) {
var existVote bool
var nftAmount common.Fixed64
var votesStakeAddress common.Uint168
+ var detailedVotes payload.DetailedVoteInfo
for _, p := range producers {
for stakeAddress, votesInfo := range p.GetAllDetailedDPoSV2Votes() {
for referKey, voteInfo := range votesInfo {
@@ -104,6 +117,7 @@ func (t *CreateNFTTransaction) SpecialContextCheck() (elaerr.ELAError, bool) {
existVote = true
nftAmount = voteInfo.Info[0].Votes
votesStakeAddress = stakeAddress
+ detailedVotes = voteInfo
}
}
}
@@ -190,5 +204,30 @@ func (t *CreateNFTTransaction) SpecialContextCheck() (elaerr.ELAError, bool) {
errors.New("vote rights is not enough")), true
}
+ if t.payloadVersion == payload.CreateNFTVersion2 {
+ if detailedVotes.BlockHeight != pld.StartHeight {
+ return elaerr.Simple(elaerr.ErrTxPayload,
+ errors.New("invalid StartHeight")), true
+ }
+ if detailedVotes.Info[0].LockTime != pld.EndHeight {
+ return elaerr.Simple(elaerr.ErrTxPayload,
+ errors.New("invalid EndHeight")), true
+ }
+ if nftAmount != pld.Votes {
+ return elaerr.Simple(elaerr.ErrTxPayload,
+ errors.New("invalid Votes")), true
+ }
+ if detailedVotes.VoteRights() != pld.VoteRights {
+ return elaerr.Simple(elaerr.ErrTxPayload,
+ errors.New("invalid VoteRights")), true
+ }
+ if !bytes.Equal(detailedVotes.Info[0].Candidate, pld.TargetOwnerKey) {
+ return elaerr.Simple(elaerr.ErrTxPayload,
+ errors.New("invalid TargetOwnerKey")), true
+ }
+ } else if t.payloadVersion > payload.CreateNFTVersion2 {
+ return elaerr.Simple(elaerr.ErrTxPayload,
+ errors.New("invalid payload version")), true
+ }
return nil, false
}
diff --git a/core/transaction/dposv2claimrewardtransaction.go b/core/transaction/dposv2claimrewardtransaction.go
index b67901515..a4883fa99 100644
--- a/core/transaction/dposv2claimrewardtransaction.go
+++ b/core/transaction/dposv2claimrewardtransaction.go
@@ -105,7 +105,7 @@ func (t *DPoSV2ClaimRewardTransaction) SpecialContextCheck() (elaerr.ELAError, b
}
if claimAmount < claimReward.Value {
- return elaerr.Simple(elaerr.ErrTxPayload, errors.New("claim reward exceeded , max claim reward "+claimAmount.String())), true
+ return elaerr.Simple(elaerr.ErrTxPayload, errors.New("claim reward exceeded , max claim reward "+claimAmount.String()+"current:"+claimAmount.String())), true
}
if claimReward.Value <= t.parameters.Config.CRConfiguration.RealWithdrawSingleFee {
@@ -149,7 +149,7 @@ func (t *DPoSV2ClaimRewardTransaction) checkClaimRewardSignature(code []byte, si
}
} else if signType == vm.CHECKMULTISIG {
// check code and signature
- if err := blockchain.CheckMultiSigSignatures(program.Program{
+ if err := crypto.CheckMultiSigSignatures(program.Program{
Code: code,
Parameter: signature,
}, data); err != nil {
diff --git a/core/transaction/dposv2claimrewardtransaction_test.go b/core/transaction/dposv2claimrewardtransaction_test.go
index ef0ee05f4..d15410d87 100644
--- a/core/transaction/dposv2claimrewardtransaction_test.go
+++ b/core/transaction/dposv2claimrewardtransaction_test.go
@@ -85,7 +85,7 @@ func (s *txValidatorTestSuite) TestCreateClaimDposV2Transaction() {
})
err, _ = tx.SpecialContextCheck()
- s.EqualError(err.(errors.ELAError).InnerError(), "claim reward exceeded , max claim reward 0.00000100")
+ s.EqualError(err.(errors.ELAError).InnerError(), "claim reward exceeded , max claim reward 0.00000100current:0.00000100")
bc = s.Chain
bc.GetState().DPoSV2RewardInfo[stakeAddr] = 10000000000
diff --git a/core/transaction/exchangevotes.go b/core/transaction/exchangevotes.go
index a28db2f17..ac9d21dc2 100644
--- a/core/transaction/exchangevotes.go
+++ b/core/transaction/exchangevotes.go
@@ -8,14 +8,15 @@ package transaction
import (
"errors"
"fmt"
- program2 "github.com/elastos/Elastos.ELA/core/contract/program"
"github.com/elastos/Elastos.ELA/common"
"github.com/elastos/Elastos.ELA/core"
"github.com/elastos/Elastos.ELA/core/contract"
+ program2 "github.com/elastos/Elastos.ELA/core/contract/program"
common2 "github.com/elastos/Elastos.ELA/core/types/common"
"github.com/elastos/Elastos.ELA/core/types/outputpayload"
"github.com/elastos/Elastos.ELA/core/types/payload"
+ "github.com/elastos/Elastos.ELA/dpos/state"
elaerr "github.com/elastos/Elastos.ELA/errors"
)
@@ -32,10 +33,17 @@ func (t *ExchangeVotesTransaction) HeightVersionCheck() error {
return errors.New(fmt.Sprintf("not support %s transaction "+
"before DPoSV2StartHeight", t.TxType().Name()))
}
+
+ if blockHeight < chainParams.MultiExchangeVotesStartHeight &&
+ len(t.programs) > 1 {
+ return errors.New(fmt.Sprintf("not support multi-addr %s transaction "+
+ "before MultiExchangeVotesStartHeight", t.TxType().Name()))
+ }
return nil
}
-func (t *ExchangeVotesTransaction) CheckTransactionOutput() error {
+// pow or before MultiExchangeVotesStartHeight
+func (t *ExchangeVotesTransaction) CheckOutputSingleInput() error {
if len(t.Outputs()) > 2 {
return errors.New("output count should not be greater than 2")
}
@@ -44,7 +52,7 @@ func (t *ExchangeVotesTransaction) CheckTransactionOutput() error {
return errors.New("transaction has no outputs")
}
- if len(t.Programs()) < 1 {
+ if len(t.Programs()) != 1 {
return errors.New("invalid programs count")
}
// check if output address is valid
@@ -103,6 +111,61 @@ func (t *ExchangeVotesTransaction) CheckTransactionOutput() error {
return nil
}
+func (t *ExchangeVotesTransaction) CheckOutputMultiInputs() error {
+ if len(t.Outputs()) < 1 {
+ return errors.New("transaction has no outputs")
+ }
+
+ if len(t.Programs()) < 1 {
+ return errors.New("invalid programs count")
+ }
+ // check if output address is valid
+ for i, output := range t.Outputs() {
+ if output.AssetID != core.ELAAssetID {
+ return errors.New("asset ID in output is invalid")
+ }
+
+ // output value must > 0
+ if output.Value <= common.Fixed64(0) {
+ return errors.New("invalid transaction UTXO output")
+ }
+ if i >= 1 {
+ if contract.GetPrefixType(output.ProgramHash) != contract.PrefixStandard &&
+ contract.GetPrefixType(output.ProgramHash) != contract.PrefixMultiSig {
+ return errors.New("second output address need to be Standard or MultiSig")
+ }
+ }
+ }
+
+ // check output payload
+ if t.outputs[0].Type != common2.OTStake {
+ return errors.New("invalid output type")
+ }
+ p := t.outputs[0].Payload
+ if p == nil {
+ return errors.New("invalid output payload")
+ }
+ if err := p.Validate(); err != nil {
+ return err
+ }
+
+ // check output address, need to be stake pool
+ if t.outputs[0].ProgramHash != *t.parameters.Config.StakePoolProgramHash {
+ return errors.New("first output address need to be stake address")
+ }
+
+ return nil
+}
+
+func (t *ExchangeVotesTransaction) CheckTransactionOutput() error {
+ inPow := t.parameters.BlockChain.GetState().GetConsensusAlgorithm() == state.POW
+ if inPow || t.parameters.BlockHeight < t.parameters.Config.MultiExchangeVotesStartHeight {
+ return t.CheckOutputSingleInput()
+ } else {
+ return t.CheckOutputMultiInputs()
+ }
+}
+
func (t *ExchangeVotesTransaction) CheckTransactionPayload() error {
switch t.Payload().(type) {
case *payload.ExchangeVotes:
@@ -119,19 +182,27 @@ func (t *ExchangeVotesTransaction) CheckAttributeProgram() error {
return fmt.Errorf("invalid attribute usage %v", attr.Usage)
}
}
-
- // Check programs
- if len(t.Programs()) != 1 {
- return errors.New("transaction should have only one program")
- }
- if t.Programs()[0].Code == nil {
- return fmt.Errorf("invalid program code nil")
- }
- if len(t.Programs()[0].Code) < program2.MinProgramCodeSize {
- return fmt.Errorf("invalid program code size")
+ if t.parameters.BlockChain.GetState().GetConsensusAlgorithm() == state.POW {
+ if len(t.Programs()) != 1 {
+ return errors.New("transaction should have one program")
+ }
+ } else {
+ // Check programs
+ if len(t.Programs()) < 1 {
+ return errors.New("transaction should have program")
+ }
}
- if t.Programs()[0].Parameter == nil {
- return fmt.Errorf("invalid program parameter nil")
+
+ for _, p := range t.Programs() {
+ if p.Code == nil {
+ return fmt.Errorf("invalid program code nil")
+ }
+ if len(p.Code) < program2.MinProgramCodeSize {
+ return fmt.Errorf("invalid program code size")
+ }
+ if p.Parameter == nil {
+ return fmt.Errorf("invalid program parameter nil")
+ }
}
return nil
@@ -144,13 +215,14 @@ func (t *ExchangeVotesTransaction) IsAllowedInPOWConsensus() bool {
func (t *ExchangeVotesTransaction) SpecialContextCheck() (result elaerr.ELAError, end bool) {
- if t.parameters.BlockHeight < t.parameters.Config.VotesSchnorrStartHeight &&
- contract.IsSchnorr(t.programs[0].Code) {
- return elaerr.Simple(elaerr.ErrTxPayload,
- errors.New(fmt.Sprintf("not support %s transaction "+
- "before VotesSchnorrStartHeight:", t.TxType().Name()))), true
-
+ if t.parameters.BlockHeight < t.parameters.Config.VotesSchnorrStartHeight {
+ for _, program := range t.programs {
+ if contract.IsSchnorr(program.Code) {
+ return elaerr.Simple(elaerr.ErrTxPayload,
+ errors.New(fmt.Sprintf("not support %s transaction "+
+ "before VotesSchnorrStartHeight:", t.TxType().Name()))), true
+ }
+ }
}
-
return nil, false
}
diff --git a/core/transaction/exchangevotes_test.go b/core/transaction/exchangevotes_test.go
index 7246c3987..7110c3296 100644
--- a/core/transaction/exchangevotes_test.go
+++ b/core/transaction/exchangevotes_test.go
@@ -3,7 +3,6 @@ package transaction
import (
"github.com/elastos/Elastos.ELA/blockchain"
"github.com/elastos/Elastos.ELA/common"
- "github.com/elastos/Elastos.ELA/common/config"
"github.com/elastos/Elastos.ELA/core"
"github.com/elastos/Elastos.ELA/core/contract"
"github.com/elastos/Elastos.ELA/core/contract/program"
@@ -60,8 +59,14 @@ func (s *txValidatorTestSuite) TestCheckStakeTransaction() {
Parameter: nil,
}},
)
+ bc := s.Chain
+ config := bc.GetParams()
+ txn.SetParameters(&TransactionParameters{
+ BlockChain: bc,
+ Config: config,
+ })
err := txn.CheckTransactionOutput()
- s.EqualError(err, "output count should not be greater than 2")
+ //s.EqualError(err, "output count should not be greater than 2")
txn = functions.CreateTransaction(
0,
@@ -77,6 +82,10 @@ func (s *txValidatorTestSuite) TestCheckStakeTransaction() {
Parameter: nil,
}},
)
+ txn.SetParameters(&TransactionParameters{
+ BlockChain: bc,
+ Config: config,
+ })
err = txn.CheckTransactionOutput()
s.EqualError(err, "transaction has no outputs")
@@ -102,6 +111,10 @@ func (s *txValidatorTestSuite) TestCheckStakeTransaction() {
Parameter: nil,
}},
)
+ txn.SetParameters(&TransactionParameters{
+ BlockChain: bc,
+ Config: config,
+ })
err = txn.CheckTransactionOutput()
s.EqualError(err, "asset ID in output is invalid")
@@ -127,6 +140,10 @@ func (s *txValidatorTestSuite) TestCheckStakeTransaction() {
Parameter: nil,
}},
)
+ txn.SetParameters(&TransactionParameters{
+ BlockChain: bc,
+ Config: config,
+ })
err = txn.CheckTransactionOutput()
s.EqualError(err, "invalid transaction UTXO output")
@@ -152,6 +169,10 @@ func (s *txValidatorTestSuite) TestCheckStakeTransaction() {
Parameter: nil,
}},
)
+ txn.SetParameters(&TransactionParameters{
+ BlockChain: bc,
+ Config: config,
+ })
err = txn.CheckTransactionOutput()
s.EqualError(err, "invalid output type")
@@ -179,6 +200,10 @@ func (s *txValidatorTestSuite) TestCheckStakeTransaction() {
Parameter: nil,
}},
)
+ txn.SetParameters(&TransactionParameters{
+ BlockChain: bc,
+ Config: config,
+ })
err = txn.CheckTransactionOutput()
s.EqualError(err, "invalid exchange vote version")
diff --git a/core/transaction/illegalproposaltransaction.go b/core/transaction/illegalproposaltransaction.go
index 814960ba6..cab60c2b2 100644
--- a/core/transaction/illegalproposaltransaction.go
+++ b/core/transaction/illegalproposaltransaction.go
@@ -1,7 +1,6 @@
// Copyright (c) 2017-2021 The Elastos Foundation
// Use of this source code is governed by an MIT
// license that can be found in the LICENSE file.
-//
package transaction
import (
diff --git a/core/transaction/illegalvotetransaction.go b/core/transaction/illegalvotetransaction.go
index 9fd47f179..ed77f42d5 100644
--- a/core/transaction/illegalvotetransaction.go
+++ b/core/transaction/illegalvotetransaction.go
@@ -1,7 +1,6 @@
// Copyright (c) 2017-2021 The Elastos Foundation
// Use of this source code is governed by an MIT
// license that can be found in the LICENSE file.
-//
package transaction
import (
@@ -102,6 +101,12 @@ func (t *IllegalVoteTransaction) CheckDPOSIllegalVotes(d *payload.DPOSIllegalVot
return errors.New("should be same sponsor")
}
+ if t.parameters.BlockHeight > t.parameters.Config.DPoSConfiguration.ChangeViewV1Height {
+ if !d.Evidence.Proposal.Hash().IsEqual(d.CompareEvidence.Proposal.Hash()) {
+ return errors.New("should be same proposal")
+ }
+ }
+
if d.Evidence.Proposal.ViewOffset != d.CompareEvidence.Proposal.ViewOffset {
return errors.New("should in same view")
}
diff --git a/core/transaction/nexttrundposinfotransaction.go b/core/transaction/nexttrundposinfotransaction.go
index 40a5807a6..b7de0f1f4 100644
--- a/core/transaction/nexttrundposinfotransaction.go
+++ b/core/transaction/nexttrundposinfotransaction.go
@@ -8,6 +8,7 @@ package transaction
import (
"bytes"
"errors"
+ "fmt"
"math"
"github.com/elastos/Elastos.ELA/blockchain"
@@ -28,6 +29,16 @@ func (t *NextTurnDPOSInfoTransaction) CheckTransactionInput() error {
return nil
}
+func (t *NextTurnDPOSInfoTransaction) HeightVersionCheck() error {
+ blockHeight := t.parameters.BlockHeight
+ chainParams := t.parameters.Config
+ if t.PayloadVersion() >= payload.NextTurnDPOSInfoVersion2 && blockHeight < chainParams.DPoSConfiguration.DexStartHeight {
+ return errors.New(fmt.Sprintf("not support %s transaction "+
+ "before DexStartHeight", t.TxType().Name()))
+ }
+ return nil
+}
+
func (t *NextTurnDPOSInfoTransaction) CheckTransactionOutput() error {
if len(t.Outputs()) > math.MaxUint16 {
@@ -87,6 +98,14 @@ func (t *NextTurnDPOSInfoTransaction) SpecialContextCheck() (elaerr.ELAError, bo
return elaerr.Simple(elaerr.ErrTxPayload, errors.New("checkNextTurnDPOSInfoTransaction nextTurnDPOSInfo was wrong")), true
}
}
+
+ if t.PayloadVersion() >= payload.NextTurnDPOSInfoVersion2 {
+ if !isCompleteArbitratorsSame(nextTurnDPOSInfo, nextCRCArbitrators) {
+ log.Warnf("[checkNextTurnDPOSInfoTransaction] CRPublicKeys %v, nextCRCArbitrators%v\n",
+ convertToArbitersStr(nextTurnDPOSInfo.CompleteCRPublicKeys), convertToArbitersStr(nextCRCArbitrators))
+ return elaerr.Simple(elaerr.ErrTxPayload, errors.New("checkNextTurnDPOSInfoTransaction nextTurnDPOSInfo was wrong")), true
+ }
+ }
return nil, true
}
@@ -154,3 +173,37 @@ func isNextArbitratorsSameV1(nextTurnDPOSInfo *payload.NextTurnDPOSInfo,
}
return true
}
+
+func isCompleteArbitratorsSame(nextTurnDPOSInfo *payload.NextTurnDPOSInfo, CRCArbitrators [][]byte) bool {
+ if len(nextTurnDPOSInfo.CompleteCRPublicKeys) != len(CRCArbitrators) {
+ log.Warn("[isCompleteArbitratorsSame] CompleteCRPublicKeys len ", len(CRCArbitrators))
+ return false
+ }
+
+ crcArbitersMap := make(map[string]struct{})
+ for _, v := range CRCArbitrators {
+ crcArbitersMap[common.BytesToHexString(v)] = struct{}{}
+ }
+ if len(crcArbitersMap) != len(CRCArbitrators) {
+ log.Warn("[isCompleteArbitratorsSame] duplicated crc arbiters")
+ return false
+ }
+
+ currentCRCArbtiersMap := make(map[string]struct{})
+ for _, v := range nextTurnDPOSInfo.CompleteCRPublicKeys {
+ currentCRCArbtiersMap[common.BytesToHexString(v)] = struct{}{}
+ }
+ if len(currentCRCArbtiersMap) != len(nextTurnDPOSInfo.CompleteCRPublicKeys) {
+ log.Warn("[isCompleteArbitratorsSame] duplicated crc arbiters in payload")
+ return false
+ }
+
+ for k, _ := range crcArbitersMap {
+ if _, ok := currentCRCArbtiersMap[k]; !ok {
+ log.Warn("[isCompleteArbitratorsSame] invalid crc arbiter in payload")
+ return false
+ }
+ }
+
+ return true
+}
diff --git a/core/transaction/registercrtransaction.go b/core/transaction/registercrtransaction.go
index 4649c592b..b4369fc94 100644
--- a/core/transaction/registercrtransaction.go
+++ b/core/transaction/registercrtransaction.go
@@ -59,6 +59,16 @@ func (t *RegisterCRTransaction) HeightVersionCheck() error {
return errors.New(fmt.Sprintf("invalid payload version, "+
"%s transaction", t.TxType().Name()))
}
+
+ if blockHeight < chainParams.DPoSConfiguration.NFTStartHeight {
+ if t.PayloadVersion() == payload.CRInfoSchnorrVersion ||
+ t.PayloadVersion() == payload.CRInfoMultiSignVersion {
+ return errors.New(fmt.Sprintf("not support %s transaction "+
+ "with payload version %d before NFTStartHeight",
+ t.TxType().Name(), t.PayloadVersion()))
+ }
+ }
+
return nil
}
@@ -92,7 +102,8 @@ func (t *RegisterCRTransaction) SpecialContextCheck() (elaerr.ELAError, bool) {
// get CID program hash and check length of code
var code []byte
- if t.payloadVersion == payload.CRInfoSchnorrVersion {
+ if t.payloadVersion == payload.CRInfoSchnorrVersion ||
+ t.payloadVersion == payload.CRInfoMultiSignVersion {
code = t.Programs()[0].Code
} else {
code = info.Code
@@ -116,8 +127,7 @@ func (t *RegisterCRTransaction) SpecialContextCheck() (elaerr.ELAError, bool) {
} else if code[len(code)-1] == vm.CHECKSIG {
pk = code[1 : len(code)-1]
} else if code[len(code)-1] == vm.CHECKMULTISIG {
- // todo complete me in the feature
- return elaerr.Simple(elaerr.ErrTxPayload, fmt.Errorf("CR not support multi sign code")), true
+ pk = code
} else {
return elaerr.Simple(elaerr.ErrTxPayload, fmt.Errorf("invalid code %s",
common.BytesToHexString(code))), true
@@ -146,7 +156,8 @@ func (t *RegisterCRTransaction) SpecialContextCheck() (elaerr.ELAError, bool) {
}
// check code and signature
- if t.payloadVersion != payload.CRInfoSchnorrVersion {
+ if t.payloadVersion != payload.CRInfoSchnorrVersion &&
+ t.payloadVersion != payload.CRInfoMultiSignVersion {
if err := blockchain.CheckPayloadSignature(info, t.PayloadVersion()); err != nil {
return elaerr.Simple(elaerr.ErrTxPayload, err), true
}
diff --git a/core/transaction/registerproducertransaction.go b/core/transaction/registerproducertransaction.go
index 6c7a157a1..cdf66e099 100644
--- a/core/transaction/registerproducertransaction.go
+++ b/core/transaction/registerproducertransaction.go
@@ -9,6 +9,7 @@ import (
"bytes"
"errors"
"fmt"
+ state2 "github.com/elastos/Elastos.ELA/dpos/state"
"github.com/elastos/Elastos.ELA/blockchain"
"github.com/elastos/Elastos.ELA/common"
@@ -20,6 +21,9 @@ import (
"github.com/elastos/Elastos.ELA/vm"
)
+// max n number for multisign producer register
+const MaxMultisignN = 10
+
type RegisterProducerTransaction struct {
BaseTransaction
}
@@ -40,6 +44,12 @@ func (t *RegisterProducerTransaction) HeightVersionCheck() error {
return errors.New(fmt.Sprintf("not support %s transaction "+
"before ProducerSchnorrStartHeight", t.TxType().Name()))
}
+ case payload.ProducerInfoMultiVersion:
+ if blockHeight < chainParams.SupportMultiCodeHeight {
+ return errors.New(fmt.Sprintf("not support %s transaction "+
+ "with payload version %d before SupportMultiCodeHeight",
+ t.TxType().Name(), t.PayloadVersion()))
+ }
default:
return errors.New(fmt.Sprintf("invalid payload version, "+
"%s transaction", t.TxType().Name()))
@@ -66,6 +76,13 @@ func (t *RegisterProducerTransaction) SpecialContextCheck() (elaerr.ELAError, bo
if !ok {
return elaerr.Simple(elaerr.ErrTxPayload, errors.New("invalid payload")), true
}
+ multiSignOwner := false
+ if t.PayloadVersion() == payload.ProducerInfoMultiVersion {
+ multiSignOwner = true
+ }
+ if multiSignOwner && len(info.OwnerKey) == crypto.NegativeBigLength {
+ return elaerr.Simple(elaerr.ErrTxPayload, errors.New("ProducerInfoMultiVersion match multi code")), true
+ }
if err := checkStringField(info.NickName, "NickName", false); err != nil {
return elaerr.Simple(elaerr.ErrTxPayload, err), true
@@ -81,19 +98,27 @@ func (t *RegisterProducerTransaction) SpecialContextCheck() (elaerr.ELAError, bo
return elaerr.Simple(elaerr.ErrTxPayload, fmt.Errorf("Same NodePublicKey producer/cr already registered")), true
}
+ nodeCode := []byte{}
+ nodeCode = append([]byte{byte(crypto.COMPRESSEDLEN)}, info.NodePublicKey...)
+ nodeCode = append(nodeCode, vm.CHECKSIG)
+
if t.parameters.BlockHeight >= t.parameters.Config.DPoSV2StartHeight {
- // OwnerPublicKey is already other's NodePublicKey
- if t.parameters.BlockChain.GetState().ProducerOrCRNodePublicKeyExists(info.OwnerPublicKey) {
- return elaerr.Simple(elaerr.ErrTxPayload, fmt.Errorf("OwnerPublicKey is already other's NodePublicKey")), true
+ // OwnerKey is already other's NodePublicKey
+ //OwnerKey will not be other's nodepublic key if OwnerKey is multicode
+ if !multiSignOwner {
+ if t.parameters.BlockChain.GetState().ProducerOrCRNodePublicKeyExists(info.OwnerKey) {
+ return elaerr.Simple(elaerr.ErrTxPayload, fmt.Errorf("OwnerKey is already other's NodePublicKey")), true
+ }
}
- // NodePublicKey is already other's OwnerPublicKey
+ // NodePublicKey is already other's OwnerKey
+ //here must check NodePublicKey as other's owner public key but no need check other's owner code
if t.parameters.BlockChain.GetState().ProducerOwnerPublicKeyExists(info.NodePublicKey) {
- return elaerr.Simple(elaerr.ErrTxPayload, fmt.Errorf("NodePublicKey is already other's OwnerPublicKey")), true
+ return elaerr.Simple(elaerr.ErrTxPayload, fmt.Errorf("NodePublicKey is already other's OwnerKey")), true
}
}
// check duplication of owner.
- if t.parameters.BlockChain.GetState().ProducerOwnerPublicKeyExists(info.OwnerPublicKey) {
+ if t.parameters.BlockChain.GetState().ProducerOwnerPublicKeyExists(info.OwnerKey) {
return elaerr.Simple(elaerr.ErrTxPayload, fmt.Errorf("producer owner already registered")), true
}
@@ -102,15 +127,19 @@ func (t *RegisterProducerTransaction) SpecialContextCheck() (elaerr.ELAError, bo
return elaerr.Simple(elaerr.ErrTxPayload, fmt.Errorf("nick name %s already inuse", info.NickName)), true
}
+ ownerCode := []byte{}
// check if public keys conflict with cr program code
- ownerCode := append([]byte{byte(crypto.COMPRESSEDLEN)}, info.OwnerPublicKey...)
- ownerCode = append(ownerCode, vm.CHECKSIG)
+ if !multiSignOwner {
+ ownerCode = append([]byte{byte(crypto.COMPRESSEDLEN)}, info.OwnerKey...)
+ ownerCode = append(ownerCode, vm.CHECKSIG)
+ } else {
+ ownerCode = info.OwnerKey
+ }
if t.parameters.BlockChain.GetCRCommittee().ExistCR(ownerCode) {
return elaerr.Simple(elaerr.ErrTxPayload, fmt.Errorf("owner public key %s already exist in cr list",
- common.BytesToHexString(info.OwnerPublicKey))), true
+ common.BytesToHexString(info.OwnerKey))), true
}
- nodeCode := append([]byte{byte(crypto.COMPRESSEDLEN)}, info.NodePublicKey...)
- nodeCode = append(nodeCode, vm.CHECKSIG)
+
if t.parameters.BlockChain.GetCRCommittee().ExistCR(nodeCode) {
return elaerr.Simple(elaerr.ErrTxPayload, fmt.Errorf("node public key %s already exist in cr list",
common.BytesToHexString(info.NodePublicKey))), true
@@ -121,11 +150,11 @@ func (t *RegisterProducerTransaction) SpecialContextCheck() (elaerr.ELAError, bo
}
// check signature
- publicKey, err := crypto.DecodePoint(info.OwnerPublicKey)
- if err != nil {
- return elaerr.Simple(elaerr.ErrTxPayload, errors.New("invalid owner public key in payload")), true
- }
- if t.PayloadVersion() != payload.ProducerInfoSchnorrVersion {
+ if t.PayloadVersion() < payload.ProducerInfoSchnorrVersion {
+ publicKey, err := crypto.DecodePoint(info.OwnerKey)
+ if err != nil {
+ return elaerr.Simple(elaerr.ErrTxPayload, errors.New("invalid owner public key in payload")), true
+ }
signedBuf := new(bytes.Buffer)
err = info.SerializeUnsigned(signedBuf, t.payloadVersion)
if err != nil {
@@ -135,7 +164,7 @@ func (t *RegisterProducerTransaction) SpecialContextCheck() (elaerr.ELAError, bo
if err != nil {
return elaerr.Simple(elaerr.ErrTxPayload, errors.New("invalid signature in payload")), true
}
- } else {
+ } else if t.PayloadVersion() == payload.ProducerInfoSchnorrVersion {
if len(t.Programs()) != 1 {
return elaerr.Simple(elaerr.ErrTxPayload,
errors.New("ProducerInfoSchnorrVersion can only have one program code")), true
@@ -145,9 +174,26 @@ func (t *RegisterProducerTransaction) SpecialContextCheck() (elaerr.ELAError, bo
errors.New("only schnorr code can use ProducerInfoSchnorrVersion")), true
}
pk := t.Programs()[0].Code[2:]
- if !bytes.Equal(pk, info.OwnerPublicKey) {
+ if !bytes.Equal(pk, info.OwnerKey) {
+ return elaerr.Simple(elaerr.ErrTxPayload,
+ errors.New("tx program pk must equal with OwnerKey")), true
+ }
+ } else if t.PayloadVersion() == payload.ProducerInfoMultiVersion {
+ if !contract.IsMultiSig(t.Programs()[0].Code) {
+ return elaerr.Simple(elaerr.ErrTxPayload,
+ errors.New("only multi sign code can use ProducerInfoMultiVersion")), true
+ }
+ //t.Programs()[0].Code equal info.OwnerKey
+ if !bytes.Equal(t.Programs()[0].Code, info.OwnerKey) {
return elaerr.Simple(elaerr.ErrTxPayload,
- errors.New("tx program pk must equal with OwnerPublicKey")), true
+ errors.New("ProducerInfoMultiVersion tx program pk must equal with OwnerKey")), true
+ }
+ //check n
+ code := t.Programs()[0].Code
+ n := int(code[len(code)-2]) - crypto.PUSH1 + 1
+ if n > MaxMultisignN {
+ return elaerr.Simple(elaerr.ErrTxPayload,
+ errors.New("multisign n can not over 10")), true
}
}
@@ -157,10 +203,13 @@ func (t *RegisterProducerTransaction) SpecialContextCheck() (elaerr.ELAError, bo
return elaerr.Simple(elaerr.ErrTxPayload, fmt.Errorf("can not register dposv2 before dposv2 start height")), true
} else if height > state.DPoSV2ActiveHeight && t.payloadVersion == payload.ProducerInfoVersion {
return elaerr.Simple(elaerr.ErrTxPayload, fmt.Errorf("can not register dposv1 after dposv2 active height")), true
+ } else if height < t.parameters.Config.SupportMultiCodeHeight && t.payloadVersion == payload.ProducerInfoMultiVersion {
+ return elaerr.Simple(elaerr.ErrTxPayload, fmt.Errorf("not support ProducerInfoMultiVersion when height is not reach SupportMultiCodeHeight")), true
}
- var hash *common.Uint168
- hash, err = contract.PublicKeyToDepositProgramHash(info.OwnerPublicKey)
+ var ownKeyProgramHash *common.Uint168
+
+ ownKeyProgramHash, err := state2.GetOwnerKeyDepositProgramHash(info.OwnerKey)
if err != nil {
return elaerr.Simple(elaerr.ErrTxPayload, errors.New("invalid public key")), true
}
@@ -170,7 +219,7 @@ func (t *RegisterProducerTransaction) SpecialContextCheck() (elaerr.ELAError, bo
for _, output := range t.Outputs() {
if contract.GetPrefixType(output.ProgramHash) == contract.PrefixDeposit {
depositCount++
- if !output.ProgramHash.IsEqual(*hash) {
+ if !output.ProgramHash.IsEqual(*ownKeyProgramHash) {
return elaerr.Simple(elaerr.ErrTxPayload, errors.New("deposit"+
" address does not match the public key in payload")), true
}
@@ -183,7 +232,7 @@ func (t *RegisterProducerTransaction) SpecialContextCheck() (elaerr.ELAError, bo
return elaerr.Simple(elaerr.ErrTxPayload, errors.New("there must be only one deposit address in outputs")), true
}
- } else if t.PayloadVersion() == payload.ProducerInfoDposV2Version || t.PayloadVersion() == payload.ProducerInfoSchnorrVersion {
+ } else {
if t.parameters.BlockHeight+t.parameters.Config.DPoSConfiguration.DPoSV2DepositCoinMinLockTime >= info.StakeUntil {
return elaerr.Simple(elaerr.ErrTxPayload, errors.New("v2 producer StakeUntil less than DPoSV2DepositCoinMinLockTime")), true
}
@@ -194,7 +243,7 @@ func (t *RegisterProducerTransaction) SpecialContextCheck() (elaerr.ELAError, bo
for _, output := range t.Outputs() {
if contract.GetPrefixType(output.ProgramHash) == contract.PrefixDeposit {
depositCount++
- if !output.ProgramHash.IsEqual(*hash) {
+ if !output.ProgramHash.IsEqual(*ownKeyProgramHash) {
return elaerr.Simple(elaerr.ErrTxPayload, errors.New("deposit address does not match the public key in payload")), true
}
if output.Value < crstate.MinDPoSV2DepositAmount {
@@ -224,13 +273,13 @@ func (t *RegisterProducerTransaction) additionalProducerInfoCheck(info *payload.
if err != nil {
return errors.New("invalid node public key in payload")
}
-
if blockchain.DefaultLedger.Arbitrators.IsCRCArbitrator(info.NodePublicKey) {
return errors.New("node public key can't equal with CRC")
}
-
- if blockchain.DefaultLedger.Arbitrators.IsCRCArbitrator(info.OwnerPublicKey) {
- return errors.New("owner public key can't equal with CRC")
+ if t.PayloadVersion() != payload.ProducerInfoMultiVersion {
+ if blockchain.DefaultLedger.Arbitrators.IsCRCArbitrator(info.OwnerKey) {
+ return errors.New("owner public key can't equal with CRC")
+ }
}
}
return nil
diff --git a/core/transaction/registerproducertransaction_test.go b/core/transaction/registerproducertransaction_test.go
index 08e0de102..0d4fe2b5f 100644
--- a/core/transaction/registerproducertransaction_test.go
+++ b/core/transaction/registerproducertransaction_test.go
@@ -27,12 +27,12 @@ func (s *txValidatorTestSuite) TestCheckRegisterProducerTransaction() {
errPublicKey, _ := common.HexStringToBytes(errPublicKeyStr)
rpPayload := &payload.ProducerInfo{
- OwnerPublicKey: publicKey1,
- NodePublicKey: publicKey1,
- NickName: "nickname 1",
- Url: "http://www.elastos_test.com",
- Location: 1,
- NetAddress: "127.0.0.1:20338",
+ OwnerKey: publicKey1,
+ NodePublicKey: publicKey1,
+ NickName: "nickname 1",
+ Url: "http://www.elastos_test.com",
+ Location: 1,
+ NetAddress: "127.0.0.1:20338",
}
rpSignBuf := new(bytes.Buffer)
err := rpPayload.SerializeUnsigned(rpSignBuf, payload.ProducerInfoVersion)
@@ -69,7 +69,7 @@ func (s *txValidatorTestSuite) TestCheckRegisterProducerTransaction() {
s.NoError(err)
// Give an invalid owner public key in payload
- txn.Payload().(*payload.ProducerInfo).OwnerPublicKey = errPublicKey
+ txn.Payload().(*payload.ProducerInfo).OwnerKey = errPublicKey
err, _ = txn.SpecialContextCheck()
s.EqualError(err, "transaction validate error: payload content invalid:invalid owner public key in payload")
@@ -82,7 +82,7 @@ func (s *txValidatorTestSuite) TestCheckRegisterProducerTransaction() {
s.EqualError(err, "transaction validate error: payload content invalid:invalid node public key in payload")
// check node public key same with CRC
- txn.Payload().(*payload.ProducerInfo).OwnerPublicKey = publicKey2
+ txn.Payload().(*payload.ProducerInfo).OwnerKey = publicKey2
pk, _ := common.HexStringToBytes(config.DefaultParams.DPoSConfiguration.CRCArbiters[0])
txn.Payload().(*payload.ProducerInfo).NodePublicKey = pk
config.DefaultParams.PublicDPOSHeight = 0
@@ -93,20 +93,20 @@ func (s *txValidatorTestSuite) TestCheckRegisterProducerTransaction() {
// check owner public key same with CRC
txn.Payload().(*payload.ProducerInfo).NodePublicKey = publicKey2
pk, _ = common.HexStringToBytes(config.DefaultParams.DPoSConfiguration.CRCArbiters[0])
- txn.Payload().(*payload.ProducerInfo).OwnerPublicKey = pk
+ txn.Payload().(*payload.ProducerInfo).OwnerKey = pk
config.DefaultParams.PublicDPOSHeight = 0
err, _ = txn.SpecialContextCheck()
config.DefaultParams.PublicDPOSHeight = originHeight
s.EqualError(err, "transaction validate error: payload content invalid:owner public key can't equal with CRC")
// Invalidates the signature in payload
- txn.Payload().(*payload.ProducerInfo).OwnerPublicKey = publicKey2
+ txn.Payload().(*payload.ProducerInfo).OwnerKey = publicKey2
txn.Payload().(*payload.ProducerInfo).NodePublicKey = publicKey2
err, _ = txn.SpecialContextCheck()
s.EqualError(err, "transaction validate error: payload content invalid:invalid signature in payload")
// Give a mismatching deposit address
- rpPayload.OwnerPublicKey = publicKey1
+ rpPayload.OwnerKey = publicKey1
rpPayload.Url = "www.test.com"
rpSignBuf = new(bytes.Buffer)
err = rpPayload.SerializeUnsigned(rpSignBuf, payload.ProducerInfoVersion)
@@ -165,13 +165,13 @@ func (s *txValidatorTestSuite) TestCheckRegisterDposV2ProducerTransaction() {
errPublicKey, _ := common.HexStringToBytes(errPublicKeyStr)
rpPayload := &payload.ProducerInfo{
- OwnerPublicKey: publicKey1,
- NodePublicKey: publicKey1,
- NickName: "nickname 1",
- Url: "http://www.elastos_test.com",
- Location: 1,
- NetAddress: "127.0.0.1:20338",
- StakeUntil: 100000,
+ OwnerKey: publicKey1,
+ NodePublicKey: publicKey1,
+ NickName: "nickname 1",
+ Url: "http://www.elastos_test.com",
+ Location: 1,
+ NetAddress: "127.0.0.1:20338",
+ StakeUntil: 100000,
}
rpSignBuf := new(bytes.Buffer)
err := rpPayload.SerializeUnsigned(rpSignBuf, payload.ProducerInfoDposV2Version)
@@ -218,7 +218,7 @@ func (s *txValidatorTestSuite) TestCheckRegisterDposV2ProducerTransaction() {
s.NoError(err)
// Give an invalid owner public key in payload
- txn.Payload().(*payload.ProducerInfo).OwnerPublicKey = errPublicKey
+ txn.Payload().(*payload.ProducerInfo).OwnerKey = errPublicKey
err, _ = tx.SpecialContextCheck()
s.EqualError(err.(errors.ELAError).InnerError(), "invalid owner public key in payload")
@@ -227,12 +227,12 @@ func (s *txValidatorTestSuite) TestCheckRegisterDposV2ProducerTransaction() {
{}, {}, {}, {},
}
param.PublicDPOSHeight = 1
- txn.Payload().(*payload.ProducerInfo).OwnerPublicKey = publicKey1
+ txn.Payload().(*payload.ProducerInfo).OwnerKey = publicKey1
err, _ = tx.SpecialContextCheck()
s.EqualError(err.(errors.ELAError).InnerError(), "can not register dposv2 before dposv2 start height")
// Invalidates public key in payload
- txn.Payload().(*payload.ProducerInfo).OwnerPublicKey = publicKey2
+ txn.Payload().(*payload.ProducerInfo).OwnerKey = publicKey2
txn.Payload().(*payload.ProducerInfo).NodePublicKey = publicKey2
param.PublicDPOSHeight = 5
s.Chain.Nodes = []*blockchain.BlockNode{
@@ -242,7 +242,7 @@ func (s *txValidatorTestSuite) TestCheckRegisterDposV2ProducerTransaction() {
s.EqualError(err.(errors.ELAError).InnerError(), "invalid signature in payload")
// Give a insufficient deposit coin
- txn.Payload().(*payload.ProducerInfo).OwnerPublicKey = publicKey1
+ txn.Payload().(*payload.ProducerInfo).OwnerKey = publicKey1
txn.Payload().(*payload.ProducerInfo).NodePublicKey = publicKey1
txn.SetOutputs([]*common2.Output{{
AssetID: common.Uint256{},
diff --git a/core/transaction/returndepositcointransaction.go b/core/transaction/returndepositcointransaction.go
index 7096b4d55..a07d133d7 100644
--- a/core/transaction/returndepositcointransaction.go
+++ b/core/transaction/returndepositcointransaction.go
@@ -8,7 +8,9 @@ package transaction
import (
"errors"
"fmt"
+ "github.com/elastos/Elastos.ELA/core/contract"
"github.com/elastos/Elastos.ELA/core/contract/program"
+ state2 "github.com/elastos/Elastos.ELA/dpos/state"
"github.com/elastos/Elastos.ELA/common"
common2 "github.com/elastos/Elastos.ELA/core/types/common"
@@ -95,8 +97,13 @@ func (t *ReturnDepositCoinTransaction) SpecialContextCheck() (elaerr.ELAError, b
}
state := t.parameters.BlockChain.GetState()
var availableAmount common.Fixed64
+ var p *state2.Producer
for _, program := range t.Programs() {
- p := state.GetProducer(program.Code[1 : len(program.Code)-1])
+ if contract.IsMultiSig(program.Code) {
+ p = state.GetProducer(program.Code)
+ } else {
+ p = state.GetProducer(program.Code[1 : len(program.Code)-1])
+ }
if p == nil {
return elaerr.Simple(elaerr.ErrTxPayload, errors.New("signer must be producer")), true
}
diff --git a/core/transaction/returndepositcointransaction_test.go b/core/transaction/returndepositcointransaction_test.go
index 5c6364590..4f979d82a 100644
--- a/core/transaction/returndepositcointransaction_test.go
+++ b/core/transaction/returndepositcointransaction_test.go
@@ -89,10 +89,10 @@ func (s *txValidatorTestSuite) TestCheckReturnDepositCoinTransaction() {
common2.RegisterProducer,
0,
&payload.ProducerInfo{
- OwnerPublicKey: publicKey,
- NodePublicKey: publicKey,
- NickName: randomString(),
- Url: randomString(),
+ OwnerKey: publicKey,
+ NodePublicKey: publicKey,
+ NickName: randomString(),
+ Url: randomString(),
},
[]*common2.Attribute{},
[]*common2.Input{},
@@ -162,7 +162,7 @@ func (s *txValidatorTestSuite) TestCheckReturnDepositCoinTransaction() {
common2.CancelProducer,
0,
&payload.ProcessProducer{
- OwnerPublicKey: publicKey,
+ OwnerKey: publicKey,
},
[]*common2.Attribute{},
[]*common2.Input{},
diff --git a/core/transaction/reverttopowtransaction.go b/core/transaction/reverttopowtransaction.go
index 69eec9289..3db25c6d8 100644
--- a/core/transaction/reverttopowtransaction.go
+++ b/core/transaction/reverttopowtransaction.go
@@ -80,7 +80,13 @@ func (t *RevertToPOWTransaction) SpecialContextCheck() (result elaerr.ELAError,
switch p.Type {
case payload.NoBlock:
lastBlockTime := int64(t.parameters.BlockChain.BestChain.Timestamp)
- noBlockTime := t.parameters.Config.DPoSConfiguration.RevertToPOWNoBlockTime
+
+ var noBlockTime int64
+ if t.parameters.BlockHeight < t.parameters.Config.DPoSConfiguration.ChangeViewV1Height {
+ noBlockTime = t.parameters.Config.DPoSConfiguration.RevertToPOWNoBlockTime
+ } else {
+ noBlockTime = t.parameters.Config.DPoSConfiguration.RevertToPOWNoBlockTimeV1
+ }
if t.parameters.TimeStamp == 0 {
// is not in block, check by local time.
diff --git a/core/transaction/transactionchecker.go b/core/transaction/transactionchecker.go
index a13bb7d35..ed58d9119 100644
--- a/core/transaction/transactionchecker.go
+++ b/core/transaction/transactionchecker.go
@@ -376,7 +376,7 @@ func (t *DefaultChecker) tryCheckVoteOutputs() error {
func getProducerPublicKeysMap(producers []*state.Producer) map[string]struct{} {
pds := make(map[string]struct{})
for _, p := range producers {
- pds[common.BytesToHexString(p.Info().OwnerPublicKey)] = struct{}{}
+ pds[common.BytesToHexString(p.Info().OwnerKey)] = struct{}{}
}
return pds
}
@@ -384,7 +384,7 @@ func getProducerPublicKeysMap(producers []*state.Producer) map[string]struct{} {
func getDPoSV2ProducersMap(producers []*state.Producer) map[string]uint32 {
pds := make(map[string]uint32)
for _, p := range producers {
- pds[common.BytesToHexString(p.Info().OwnerPublicKey)] = p.Info().StakeUntil
+ pds[common.BytesToHexString(p.Info().OwnerKey)] = p.Info().StakeUntil
}
return pds
}
diff --git a/core/transaction/unregistercrtransaction.go b/core/transaction/unregistercrtransaction.go
index c30c39ef5..7456644f8 100644
--- a/core/transaction/unregistercrtransaction.go
+++ b/core/transaction/unregistercrtransaction.go
@@ -67,7 +67,8 @@ func (t *UnregisterCRTransaction) SpecialContextCheck() (elaerr.ELAError, bool)
if err != nil {
return elaerr.Simple(elaerr.ErrTxPayload, err), true
}
- if t.payloadVersion != payload.UnregisterCRSchnorrVersion {
+ if t.payloadVersion != payload.UnregisterCRSchnorrVersion &&
+ t.payloadVersion != payload.UnregisterCRMultiVersion {
err = blockchain.CheckCRTransactionSignature(info.Signature, cr.Info.Code, signedBuf.Bytes())
if err != nil {
return elaerr.Simple(elaerr.ErrTxPayload, err), true
diff --git a/core/transaction/updatecrtransaction.go b/core/transaction/updatecrtransaction.go
index 65aa5a6c7..c94db59d3 100644
--- a/core/transaction/updatecrtransaction.go
+++ b/core/transaction/updatecrtransaction.go
@@ -50,7 +50,8 @@ func (t *UpdateCRTransaction) SpecialContextCheck() (elaerr.ELAError, bool) {
}
var code []byte
- if t.payloadVersion == payload.CRInfoSchnorrVersion {
+ if t.payloadVersion == payload.CRInfoSchnorrVersion ||
+ t.payloadVersion == payload.CRInfoMultiSignVersion {
code = t.Programs()[0].Code
} else {
code = info.Code
@@ -101,7 +102,8 @@ func (t *UpdateCRTransaction) SpecialContextCheck() (elaerr.ELAError, bool) {
}
// check code and signature
- if t.payloadVersion != payload.CRInfoSchnorrVersion {
+ if t.payloadVersion != payload.CRInfoSchnorrVersion &&
+ t.payloadVersion != payload.CRInfoMultiSignVersion {
if err := blockchain.CheckPayloadSignature(info, t.PayloadVersion()); err != nil {
return elaerr.Simple(elaerr.ErrTxPayload, err), true
}
diff --git a/core/transaction/updateproducertransaction.go b/core/transaction/updateproducertransaction.go
index 07fb41998..c6fb9e4cd 100644
--- a/core/transaction/updateproducertransaction.go
+++ b/core/transaction/updateproducertransaction.go
@@ -38,6 +38,13 @@ func (t *UpdateProducerTransaction) HeightVersionCheck() error {
"2.0 producer transaction before RevertToPOWStartHeight")
}
}
+ if blockHeight < chainParams.SupportMultiCodeHeight {
+ if t.PayloadVersion() == payload.ProducerInfoMultiVersion {
+ return errors.New(fmt.Sprintf("not support %s transaction "+
+ "with payload version %d before SupportMultiCodeHeight",
+ t.TxType().Name(), t.PayloadVersion()))
+ }
+ }
return nil
}
@@ -77,7 +84,13 @@ func (t *UpdateProducerTransaction) SpecialContextCheck() (elaerr.ELAError, bool
if !ok {
return elaerr.Simple(elaerr.ErrTxPayload, errors.New("invalid payload")), true
}
-
+ multiSignOwner := false
+ if t.PayloadVersion() == payload.ProducerInfoMultiVersion {
+ multiSignOwner = true
+ }
+ if multiSignOwner && len(info.OwnerKey) == crypto.NegativeBigLength {
+ return elaerr.Simple(elaerr.ErrTxPayload, errors.New("ProducerInfoMultiVersion match multi code")), true
+ }
// check nick name
if err := checkStringField(info.NickName, "NickName", false); err != nil {
return elaerr.Simple(elaerr.ErrTxPayload, err), true
@@ -92,18 +105,11 @@ func (t *UpdateProducerTransaction) SpecialContextCheck() (elaerr.ELAError, bool
return elaerr.Simple(elaerr.ErrTxPayload, err), true
}
- // check signature
- publicKey, err := crypto.DecodePoint(info.OwnerPublicKey)
- if err != nil {
- return elaerr.Simple(elaerr.ErrTxPayload, errors.New("invalid owner public key in payload")), true
- }
- signedBuf := new(bytes.Buffer)
- err = info.SerializeUnsigned(signedBuf, t.payloadVersion)
- if err != nil {
- return elaerr.Simple(elaerr.ErrTxPayload, err), true
- }
-
- if t.PayloadVersion() != payload.ProducerInfoSchnorrVersion {
+ if t.PayloadVersion() < payload.ProducerInfoSchnorrVersion {
+ publicKey, err := crypto.DecodePoint(info.OwnerKey)
+ if err != nil {
+ return elaerr.Simple(elaerr.ErrTxPayload, errors.New("invalid owner public key in payload")), true
+ }
signedBuf := new(bytes.Buffer)
err = info.SerializeUnsigned(signedBuf, t.payloadVersion)
if err != nil {
@@ -113,7 +119,7 @@ func (t *UpdateProducerTransaction) SpecialContextCheck() (elaerr.ELAError, bool
if err != nil {
return elaerr.Simple(elaerr.ErrTxPayload, errors.New("invalid signature in payload")), true
}
- } else {
+ } else if t.PayloadVersion() == payload.ProducerInfoSchnorrVersion {
if len(t.Programs()) != 1 {
return elaerr.Simple(elaerr.ErrTxPayload,
errors.New("ProducerInfoSchnorrVersion can only have one program code")), true
@@ -123,13 +129,23 @@ func (t *UpdateProducerTransaction) SpecialContextCheck() (elaerr.ELAError, bool
errors.New("only schnorr code can use ProducerInfoSchnorrVersion")), true
}
pk := t.Programs()[0].Code[2:]
- if !bytes.Equal(pk, info.OwnerPublicKey) {
+ if !bytes.Equal(pk, info.OwnerKey) {
+ return elaerr.Simple(elaerr.ErrTxPayload,
+ errors.New("tx program pk must equal with OwnerKey")), true
+ }
+ } else if t.PayloadVersion() == payload.ProducerInfoMultiVersion {
+ if !contract.IsMultiSig(t.Programs()[0].Code) {
+ return elaerr.Simple(elaerr.ErrTxPayload,
+ errors.New("only multi sign code can use ProducerInfoMultiVersion")), true
+ }
+ //t.Programs()[0].Code equal info.OwnerKey
+ if !bytes.Equal(t.Programs()[0].Code, info.OwnerKey) {
return elaerr.Simple(elaerr.ErrTxPayload,
- errors.New("tx program pk must equal with OwnerPublicKey")), true
+ errors.New("ProducerInfoMultiVersion tx program pk must equal with OwnerKey")), true
}
}
- producer := t.parameters.BlockChain.GetState().GetProducer(info.OwnerPublicKey)
+ producer := t.parameters.BlockChain.GetState().GetProducer(info.OwnerKey)
if producer == nil {
return elaerr.Simple(elaerr.ErrTxPayload, errors.New("updating unknown producer")), true
}
@@ -189,7 +205,7 @@ func (t *UpdateProducerTransaction) SpecialContextCheck() (elaerr.ELAError, bool
common.BytesToHexString(info.NodePublicKey))), true
}
- // It is not necessary to check if OwnerPublicKey is others' NodePublicKey since we can not change OwnerPublicKey
+ // It is not necessary to check if OwnerKey is others' NodePublicKey since we can not change OwnerKey
// check node public key duplication
if bytes.Equal(info.NodePublicKey, producer.Info().NodePublicKey) {
@@ -211,9 +227,9 @@ func (t *UpdateProducerTransaction) SpecialContextCheck() (elaerr.ELAError, bool
if t.parameters.BlockHeight > t.parameters.Config.DPoSV2StartHeight {
//check if NodePublicKey is others' ownerpublickey
- //NodePublicKey can not be change into one producer's OwnerPublicKey only if it is the same producer.
+ //NodePublicKey can not be change into one producer's OwnerKey only if it is the same producer.
producer := t.parameters.BlockChain.GetState().GetProducerByOwnerPublicKey(info.NodePublicKey)
- if producer != nil && !bytes.Equal(info.OwnerPublicKey, producer.OwnerPublicKey()) {
+ if producer != nil && !bytes.Equal(info.OwnerKey, producer.OwnerPublicKey()) {
return elaerr.Simple(elaerr.ErrTxPayload, fmt.Errorf("NodePublicKey %s can not be other producer's ownerPublicKey ",
hex.EncodeToString(info.NodePublicKey))), true
}
diff --git a/core/transaction/updateproducertransaction_test.go b/core/transaction/updateproducertransaction_test.go
index 47c769a17..71686cf8f 100644
--- a/core/transaction/updateproducertransaction_test.go
+++ b/core/transaction/updateproducertransaction_test.go
@@ -28,12 +28,12 @@ func (s *txValidatorTestSuite) TestCheckUpdateProducerTransaction() {
errPublicKey, _ := common.HexStringToBytes(errPublicKeyStr)
registerPayload := &payload.ProducerInfo{
- OwnerPublicKey: publicKey1,
- NodePublicKey: publicKey1,
- NickName: "",
- Url: "",
- Location: 1,
- NetAddress: "",
+ OwnerKey: publicKey1,
+ NodePublicKey: publicKey1,
+ NickName: "",
+ Url: "",
+ Location: 1,
+ NetAddress: "",
}
programs := []*program.Program{{
Code: getCodeByPubKeyStr(publicKeyStr1),
@@ -85,12 +85,12 @@ func (s *txValidatorTestSuite) TestCheckUpdateProducerTransaction() {
txn.SetTxType(common2.UpdateProducer)
updatePayload := &payload.ProducerInfo{
- OwnerPublicKey: publicKey1,
- NodePublicKey: publicKey1,
- NickName: "",
- Url: "",
- Location: 2,
- NetAddress: "",
+ OwnerKey: publicKey1,
+ NodePublicKey: publicKey1,
+ NickName: "",
+ Url: "",
+ Location: 2,
+ NetAddress: "",
}
txn.SetPayload(updatePayload)
s.CurrentHeight++
@@ -102,7 +102,7 @@ func (s *txValidatorTestSuite) TestCheckUpdateProducerTransaction() {
updatePayload.NickName = "nick name"
updatePayload.Url = "www.elastos.org"
- updatePayload.OwnerPublicKey = errPublicKey
+ updatePayload.OwnerKey = errPublicKey
err, _ = txn.SpecialContextCheck()
s.EqualError(err, "transaction validate error: payload content invalid:invalid owner public key in payload")
@@ -115,7 +115,7 @@ func (s *txValidatorTestSuite) TestCheckUpdateProducerTransaction() {
config.DefaultParams.PublicDPOSHeight = originHeight
// check node public key same with CRC
- txn.Payload().(*payload.ProducerInfo).OwnerPublicKey = publicKey2
+ txn.Payload().(*payload.ProducerInfo).OwnerKey = publicKey2
pk, _ := common.HexStringToBytes(config.DefaultParams.DPoSConfiguration.CRCArbiters[0])
txn.Payload().(*payload.ProducerInfo).NodePublicKey = pk
config.DefaultParams.PublicDPOSHeight = 0
@@ -126,18 +126,18 @@ func (s *txValidatorTestSuite) TestCheckUpdateProducerTransaction() {
// check owner public key same with CRC
txn.Payload().(*payload.ProducerInfo).NodePublicKey = publicKey2
pk, _ = common.HexStringToBytes(config.DefaultParams.DPoSConfiguration.CRCArbiters[0])
- txn.Payload().(*payload.ProducerInfo).OwnerPublicKey = pk
+ txn.Payload().(*payload.ProducerInfo).OwnerKey = pk
config.DefaultParams.PublicDPOSHeight = 0
err, _ = txn.SpecialContextCheck()
config.DefaultParams.PublicDPOSHeight = originHeight
s.EqualError(err, "transaction validate error: payload content invalid:invalid signature in payload")
- updatePayload.OwnerPublicKey = publicKey2
+ updatePayload.OwnerKey = publicKey2
updatePayload.NodePublicKey = publicKey1
err, _ = txn.SpecialContextCheck()
s.EqualError(err, "transaction validate error: payload content invalid:invalid signature in payload")
- updatePayload.OwnerPublicKey = publicKey1
+ updatePayload.OwnerKey = publicKey1
updateSignBuf := new(bytes.Buffer)
err1 := updatePayload.SerializeUnsigned(updateSignBuf, payload.ProducerInfoVersion)
s.NoError(err1)
@@ -161,12 +161,12 @@ func (s *txValidatorTestSuite) TestCheckUpdateProducerV1V2Transaction() {
errPublicKey, _ := common.HexStringToBytes(errPublicKeyStr)
registerPayload := &payload.ProducerInfo{
- OwnerPublicKey: publicKey1,
- NodePublicKey: publicKey1,
- NickName: "",
- Url: "",
- Location: 1,
- NetAddress: "",
+ OwnerKey: publicKey1,
+ NodePublicKey: publicKey1,
+ NickName: "",
+ Url: "",
+ Location: 1,
+ NetAddress: "",
}
programs := []*program.Program{{
Code: getCodeByPubKeyStr(publicKeyStr1),
@@ -218,13 +218,13 @@ func (s *txValidatorTestSuite) TestCheckUpdateProducerV1V2Transaction() {
txn.SetTxType(common2.UpdateProducer)
updatePayload := &payload.ProducerInfo{
- OwnerPublicKey: publicKey1,
- NodePublicKey: publicKey1,
- NickName: "",
- Url: "",
- Location: 2,
- NetAddress: "",
- StakeUntil: 10,
+ OwnerKey: publicKey1,
+ NodePublicKey: publicKey1,
+ NickName: "",
+ Url: "",
+ Location: 2,
+ NetAddress: "",
+ StakeUntil: 10,
}
txn.SetPayload(updatePayload)
s.CurrentHeight++
@@ -236,7 +236,7 @@ func (s *txValidatorTestSuite) TestCheckUpdateProducerV1V2Transaction() {
updatePayload.NickName = "nick name"
updatePayload.Url = "www.elastos.org"
- updatePayload.OwnerPublicKey = errPublicKey
+ updatePayload.OwnerKey = errPublicKey
err, _ = txn.SpecialContextCheck()
s.EqualError(err, "transaction validate error: payload content invalid:invalid owner public key in payload")
@@ -249,7 +249,7 @@ func (s *txValidatorTestSuite) TestCheckUpdateProducerV1V2Transaction() {
config.DefaultParams.PublicDPOSHeight = originHeight
// check node public key same with CRC
- txn.Payload().(*payload.ProducerInfo).OwnerPublicKey = publicKey2
+ txn.Payload().(*payload.ProducerInfo).OwnerKey = publicKey2
pk, _ := common.HexStringToBytes(config.DefaultParams.DPoSConfiguration.CRCArbiters[0])
txn.Payload().(*payload.ProducerInfo).NodePublicKey = pk
config.DefaultParams.PublicDPOSHeight = 0
@@ -260,18 +260,18 @@ func (s *txValidatorTestSuite) TestCheckUpdateProducerV1V2Transaction() {
// check owner public key same with CRC
txn.Payload().(*payload.ProducerInfo).NodePublicKey = publicKey2
pk, _ = common.HexStringToBytes(config.DefaultParams.DPoSConfiguration.CRCArbiters[0])
- txn.Payload().(*payload.ProducerInfo).OwnerPublicKey = pk
+ txn.Payload().(*payload.ProducerInfo).OwnerKey = pk
config.DefaultParams.PublicDPOSHeight = 0
err, _ = txn.SpecialContextCheck()
config.DefaultParams.PublicDPOSHeight = originHeight
s.EqualError(err, "transaction validate error: payload content invalid:invalid signature in payload")
- updatePayload.OwnerPublicKey = publicKey2
+ updatePayload.OwnerKey = publicKey2
updatePayload.NodePublicKey = publicKey1
err, _ = txn.SpecialContextCheck()
s.EqualError(err, "transaction validate error: payload content invalid:invalid signature in payload")
- updatePayload.OwnerPublicKey = publicKey1
+ updatePayload.OwnerKey = publicKey1
updateSignBuf := new(bytes.Buffer)
err1 := updatePayload.SerializeUnsigned(updateSignBuf, payload.ProducerInfoVersion)
s.NoError(err1)
@@ -325,13 +325,13 @@ func (s *txValidatorTestSuite) TestCheckUpdateProducerV2Transaction() {
errPublicKey, _ := common.HexStringToBytes(errPublicKeyStr)
registerPayload := &payload.ProducerInfo{
- OwnerPublicKey: publicKey1,
- NodePublicKey: publicKey1,
- NickName: "",
- Url: "",
- Location: 1,
- NetAddress: "",
- StakeUntil: 100,
+ OwnerKey: publicKey1,
+ NodePublicKey: publicKey1,
+ NickName: "",
+ Url: "",
+ Location: 1,
+ NetAddress: "",
+ StakeUntil: 100,
}
programs := []*program.Program{{
Code: getCodeByPubKeyStr(publicKeyStr1),
@@ -383,13 +383,13 @@ func (s *txValidatorTestSuite) TestCheckUpdateProducerV2Transaction() {
txn.SetTxType(common2.UpdateProducer)
updatePayload := &payload.ProducerInfo{
- OwnerPublicKey: publicKey1,
- NodePublicKey: publicKey1,
- NickName: "",
- Url: "",
- Location: 2,
- NetAddress: "",
- StakeUntil: 1000,
+ OwnerKey: publicKey1,
+ NodePublicKey: publicKey1,
+ NickName: "",
+ Url: "",
+ Location: 2,
+ NetAddress: "",
+ StakeUntil: 1000,
}
txn.SetPayload(updatePayload)
s.CurrentHeight++
@@ -401,7 +401,7 @@ func (s *txValidatorTestSuite) TestCheckUpdateProducerV2Transaction() {
updatePayload.NickName = "nick name"
updatePayload.Url = "www.elastos.org"
- updatePayload.OwnerPublicKey = errPublicKey
+ updatePayload.OwnerKey = errPublicKey
err, _ = txn.SpecialContextCheck()
s.EqualError(err, "transaction validate error: payload content invalid:invalid owner public key in payload")
@@ -414,7 +414,7 @@ func (s *txValidatorTestSuite) TestCheckUpdateProducerV2Transaction() {
config.DefaultParams.PublicDPOSHeight = originHeight
// check node public key same with CRC
- txn.Payload().(*payload.ProducerInfo).OwnerPublicKey = publicKey2
+ txn.Payload().(*payload.ProducerInfo).OwnerKey = publicKey2
pk, _ := common.HexStringToBytes(config.DefaultParams.DPoSConfiguration.CRCArbiters[0])
txn.Payload().(*payload.ProducerInfo).NodePublicKey = pk
config.DefaultParams.PublicDPOSHeight = 0
@@ -425,18 +425,18 @@ func (s *txValidatorTestSuite) TestCheckUpdateProducerV2Transaction() {
// check owner public key same with CRC
txn.Payload().(*payload.ProducerInfo).NodePublicKey = publicKey2
pk, _ = common.HexStringToBytes(config.DefaultParams.DPoSConfiguration.CRCArbiters[0])
- txn.Payload().(*payload.ProducerInfo).OwnerPublicKey = pk
+ txn.Payload().(*payload.ProducerInfo).OwnerKey = pk
config.DefaultParams.PublicDPOSHeight = 0
err, _ = txn.SpecialContextCheck()
config.DefaultParams.PublicDPOSHeight = originHeight
s.EqualError(err, "transaction validate error: payload content invalid:invalid signature in payload")
- updatePayload.OwnerPublicKey = publicKey2
+ updatePayload.OwnerKey = publicKey2
updatePayload.NodePublicKey = publicKey1
err, _ = txn.SpecialContextCheck()
s.EqualError(err, "transaction validate error: payload content invalid:invalid signature in payload")
- updatePayload.OwnerPublicKey = publicKey1
+ updatePayload.OwnerKey = publicKey1
updateSignBuf := new(bytes.Buffer)
err1 := updatePayload.SerializeUnsigned(updateSignBuf, payload.ProducerInfoVersion)
s.NoError(err1)
diff --git a/core/types/outputpayload/mapping.go b/core/types/outputpayload/mapping.go
index 9840f34bd..b0aa2eb3a 100644
--- a/core/types/outputpayload/mapping.go
+++ b/core/types/outputpayload/mapping.go
@@ -11,6 +11,7 @@ import (
"io"
"github.com/elastos/Elastos.ELA/common"
+ "github.com/elastos/Elastos.ELA/core/contract/program"
"github.com/elastos/Elastos.ELA/crypto"
)
@@ -25,8 +26,8 @@ type Mapping struct {
// Version indicates the version of Mapping payload.
Version byte
- // OwnerPublicKey is the owner public key of the main chain producer.
- OwnerPublicKey []byte
+ // OwnerKey is the owner public key of the main chain producer.
+ OwnerKey []byte
// SideProducerID indicates a piece of data represent the identity of the
// side chain producer, whether it is a public key or address etc.
@@ -47,7 +48,7 @@ func (m *Mapping) serializeContent(w io.Writer) error {
return err
}
- if err := common.WriteVarBytes(w, m.OwnerPublicKey); err != nil {
+ if err := common.WriteVarBytes(w, m.OwnerKey); err != nil {
return err
}
@@ -69,8 +70,8 @@ func (m *Mapping) Deserialize(r io.Reader) error {
return err
}
- m.OwnerPublicKey, err = common.ReadVarBytes(r, crypto.COMPRESSEDLEN,
- "OwnerPublicKey")
+ m.OwnerKey, err = common.ReadVarBytes(r, crypto.MaxMultiSignCodeLength,
+ "OwnerKey")
if err != nil {
return err
}
@@ -91,15 +92,24 @@ func (m *Mapping) GetVersion() byte {
}
func (m *Mapping) Validate() error {
- pubKey, err := crypto.DecodePoint(m.OwnerPublicKey)
- if err != nil {
- return errors.New("mapping invalid OwnerPublicKey")
+ if len(m.OwnerKey) == crypto.NegativeBigLength {
+ pubKey, err := crypto.DecodePoint(m.OwnerKey)
+ if err != nil {
+ return errors.New("mapping invalid OwnerKey")
+ }
+
+ err = crypto.Verify(*pubKey, m.Data(), m.Signature)
+ if err != nil {
+ return errors.New("invalid content signature")
+ }
+ } else {
+ // check CheckMultiSigSignatures
+ if err := crypto.CheckMultiSigSignatures(program.Program{
+ Code: m.OwnerKey,
+ Parameter: m.Signature,
+ }, m.Data()); err != nil {
+ return err
+ }
}
-
- err = crypto.Verify(*pubKey, m.Data(), m.Signature)
- if err != nil {
- return errors.New("invalid content signature")
- }
-
return nil
}
diff --git a/core/types/outputpayload/mapping_test.go b/core/types/outputpayload/mapping_test.go
index e99708327..3868aae6b 100644
--- a/core/types/outputpayload/mapping_test.go
+++ b/core/types/outputpayload/mapping_test.go
@@ -17,7 +17,7 @@ import (
func TestMapping_Serialize(t *testing.T) {
m := Mapping{}
priKey, pubKey, err := crypto.GenerateKeyPair()
- m.OwnerPublicKey, _ = pubKey.EncodePoint(true)
+ m.OwnerKey, _ = pubKey.EncodePoint(true)
m.SideProducerID = make([]byte, 33)
m.Signature, _ = crypto.Sign(priKey, m.Data())
@@ -26,7 +26,7 @@ func TestMapping_Serialize(t *testing.T) {
assert.NoError(t, err)
// 1 byte(Version)
- // 1 byte(len) + 33 bytes(OwnerPublicKey)
+ // 1 byte(len) + 33 bytes(OwnerKey)
// 1 byte(len) + 33 bytes(SideProducerID)
// 1 byte(len) + 64 bytes(Signature)
// = 134 bytes
@@ -38,8 +38,8 @@ func TestMapping_Serialize(t *testing.T) {
func TestMapping_Deserialize(t *testing.T) {
m := Mapping{}
- // OwnerPublicKey over size.
- m.OwnerPublicKey = make([]byte, 34)
+ // OwnerKey over size.
+ m.OwnerKey = make([]byte, crypto.MaxMultiSignCodeLength+1)
m.SideProducerID = make([]byte, 33)
buf := new(bytes.Buffer)
err := m.Serialize(buf)
@@ -48,7 +48,7 @@ func TestMapping_Deserialize(t *testing.T) {
assert.Error(t, err)
// SideProducerID over size.
- m.OwnerPublicKey = make([]byte, 33)
+ m.OwnerKey = make([]byte, 33)
m.SideProducerID = make([]byte, 257)
buf = new(bytes.Buffer)
err = m.Serialize(buf)
@@ -60,7 +60,7 @@ func TestMapping_Deserialize(t *testing.T) {
m1, m2 := Mapping{}, Mapping{}
m1.Version = 2
priKey, pubKey, err := crypto.GenerateKeyPair()
- m1.OwnerPublicKey, _ = pubKey.EncodePoint(true)
+ m1.OwnerKey, _ = pubKey.EncodePoint(true)
m1.SideProducerID = make([]byte, 33)
rand.Read(m1.SideProducerID)
m1.Signature, _ = crypto.Sign(priKey, m1.Data())
@@ -80,7 +80,7 @@ func TestMapping_Deserialize(t *testing.T) {
func TestMapping_Validate(t *testing.T) {
m := Mapping{}
- m.OwnerPublicKey = make([]byte, 33)
+ m.OwnerKey = make([]byte, 33)
m.SideProducerID = make([]byte, 33)
err := m.Validate()
assert.Error(t, err)
diff --git a/core/types/payload/crcproposal.go b/core/types/payload/crcproposal.go
index df0607d9f..b8a184313 100644
--- a/core/types/payload/crcproposal.go
+++ b/core/types/payload/crcproposal.go
@@ -146,8 +146,8 @@ type CRCProposal struct {
// with a length limit not exceeding 4096 characters
CategoryData string
- // Public key of proposal owner.
- OwnerPublicKey []byte
+ // Public key or multsin code of proposal owner.
+ OwnerKey []byte
// The hash of draft proposal.
DraftHash common.Uint256
@@ -179,8 +179,8 @@ type CRCProposal struct {
// The specified ELA address where the funds are to be sent.
NewRecipient common.Uint168
- // New public key of proposal owner.
- NewOwnerPublicKey []byte
+ // New public key or multsin code of proposal owner.
+ NewOwnerKey []byte
// Public key of SecretaryGeneral.
SecretaryGeneralPublicKey []byte
@@ -434,8 +434,8 @@ func (p *CRCProposal) SerializeUnsignedNormalOrELIP(w io.Writer, version byte) e
return errors.New("failed to serialize CategoryData")
}
- if err := common.WriteVarBytes(w, p.OwnerPublicKey); err != nil {
- return errors.New("failed to serialize OwnerPublicKey")
+ if err := common.WriteVarBytes(w, p.OwnerKey); err != nil {
+ return errors.New("failed to serialize OwnerKey")
}
if err := p.DraftHash.Serialize(w); err != nil {
@@ -472,8 +472,8 @@ func (p *CRCProposal) SerializeUnsignedChangeProposalOwner(w io.Writer, version
if err := common.WriteVarString(w, p.CategoryData); err != nil {
return errors.New("failed to serialize CategoryData")
}
- if err := common.WriteVarBytes(w, p.OwnerPublicKey); err != nil {
- return errors.New("failed to serialize OwnerPublicKey")
+ if err := common.WriteVarBytes(w, p.OwnerKey); err != nil {
+ return errors.New("failed to serialize OwnerKey")
}
if err := p.DraftHash.Serialize(w); err != nil {
return errors.New("failed to serialize DraftHash")
@@ -489,8 +489,8 @@ func (p *CRCProposal) SerializeUnsignedChangeProposalOwner(w io.Writer, version
if err := p.NewRecipient.Serialize(w); err != nil {
return errors.New("failed to serialize Recipient")
}
- if err := common.WriteVarBytes(w, p.NewOwnerPublicKey); err != nil {
- return errors.New("failed to serialize NewOwnerPublicKey")
+ if err := common.WriteVarBytes(w, p.NewOwnerKey); err != nil {
+ return errors.New("failed to serialize NewOwnerKey")
}
return nil
}
@@ -504,8 +504,8 @@ func (p *CRCProposal) SerializeUnsignedChangeSecretaryGeneral(w io.Writer, versi
return errors.New("failed to serialize CategoryData")
}
- if err := common.WriteVarBytes(w, p.OwnerPublicKey); err != nil {
- return errors.New("failed to serialize OwnerPublicKey")
+ if err := common.WriteVarBytes(w, p.OwnerKey); err != nil {
+ return errors.New("failed to serialize OwnerKey")
}
if err := p.DraftHash.Serialize(w); err != nil {
@@ -536,8 +536,8 @@ func (p *CRCProposal) SerializeUnsignedUpgradeCode(w io.Writer, version byte) er
return errors.New("failed to serialize CategoryData")
}
- if err := common.WriteVarBytes(w, p.OwnerPublicKey); err != nil {
- return errors.New("failed to serialize OwnerPublicKey")
+ if err := common.WriteVarBytes(w, p.OwnerKey); err != nil {
+ return errors.New("failed to serialize OwnerKey")
}
if err := p.DraftHash.Serialize(w); err != nil {
@@ -561,8 +561,8 @@ func (p *CRCProposal) SerializeUnsignedRegisterSideChain(w io.Writer, version by
return errors.New("[CRCProposal], Category Data serialize failed")
}
- if err := common.WriteVarBytes(w, p.OwnerPublicKey); err != nil {
- return errors.New("failed to serialize OwnerPublicKey")
+ if err := common.WriteVarBytes(w, p.OwnerKey); err != nil {
+ return errors.New("failed to serialize OwnerKey")
}
if err := p.DraftHash.Serialize(w); err != nil {
@@ -592,8 +592,8 @@ func (p *CRCProposal) SerializeUnsignedCloseProposal(w io.Writer, version byte)
return errors.New("failed to serialize CategoryData")
}
- if err := common.WriteVarBytes(w, p.OwnerPublicKey); err != nil {
- return errors.New("failed to serialize OwnerPublicKey")
+ if err := common.WriteVarBytes(w, p.OwnerKey); err != nil {
+ return errors.New("failed to serialize OwnerKey")
}
if err := p.DraftHash.Serialize(w); err != nil {
@@ -621,8 +621,8 @@ func (p *CRCProposal) SerializeUnsignedChangeCustomIDFee(w io.Writer, version by
return errors.New("failed to serialize CategoryData")
}
- if err := common.WriteVarBytes(w, p.OwnerPublicKey); err != nil {
- return errors.New("failed to serialize OwnerPublicKey")
+ if err := common.WriteVarBytes(w, p.OwnerKey); err != nil {
+ return errors.New("failed to serialize OwnerKey")
}
if err := p.DraftHash.Serialize(w); err != nil {
@@ -651,8 +651,8 @@ func (p *CRCProposal) SerializeUnsignedReceivedCustomID(w io.Writer, version byt
return errors.New("failed to serialize CategoryData")
}
- if err := common.WriteVarBytes(w, p.OwnerPublicKey); err != nil {
- return errors.New("failed to serialize OwnerPublicKey")
+ if err := common.WriteVarBytes(w, p.OwnerKey); err != nil {
+ return errors.New("failed to serialize OwnerKey")
}
if err := p.DraftHash.Serialize(w); err != nil {
@@ -691,8 +691,8 @@ func (p *CRCProposal) SerializeUnsignedReservedCustomID(w io.Writer, version byt
return errors.New("[CRCProposal], Category Data serialize failed")
}
- if err := common.WriteVarBytes(w, p.OwnerPublicKey); err != nil {
- return errors.New("failed to serialize OwnerPublicKey")
+ if err := common.WriteVarBytes(w, p.OwnerKey); err != nil {
+ return errors.New("failed to serialize OwnerKey")
}
if err := p.DraftHash.Serialize(w); err != nil {
@@ -882,8 +882,8 @@ func (p *CRCProposal) DeserializeUnsignedUpgradeCode(r io.Reader, version byte)
if p.CategoryData, err = common.ReadVarString(r); err != nil {
return errors.New("[CRCProposal], Category data deserialize failed")
}
- if p.OwnerPublicKey, err = common.ReadVarBytes(r, crypto.NegativeBigLength, "owner"); err != nil {
- return errors.New("failed to deserialize OwnerPublicKey")
+ if p.OwnerKey, err = common.ReadVarBytes(r, crypto.NegativeBigLength, "owner"); err != nil {
+ return errors.New("failed to deserialize OwnerKey")
}
if err = p.DraftHash.Deserialize(r); err != nil {
return errors.New("failed to deserialize DraftHash")
@@ -904,9 +904,9 @@ func (p *CRCProposal) DeserializeUnSignedNormalOrELIP(r io.Reader, version byte)
return errors.New("[CRCProposal], Category data deserialize failed")
}
- p.OwnerPublicKey, err = common.ReadVarBytes(r, crypto.NegativeBigLength, "owner")
+ p.OwnerKey, err = common.ReadVarBytes(r, crypto.NegativeBigLength, "owner")
if err != nil {
- return errors.New("failed to deserialize OwnerPublicKey")
+ return errors.New("failed to deserialize OwnerKey")
}
if err = p.DraftHash.Deserialize(r); err != nil {
@@ -943,8 +943,8 @@ func (p *CRCProposal) DeserializeUnSignedChangeProposalOwner(r io.Reader, versio
if p.CategoryData, err = common.ReadVarString(r); err != nil {
return errors.New("[CRCProposal], Category data deserialize failed")
}
- if p.OwnerPublicKey, err = common.ReadVarBytes(r, crypto.NegativeBigLength, "owner"); err != nil {
- return errors.New("failed to deserialize OwnerPublicKey")
+ if p.OwnerKey, err = common.ReadVarBytes(r, crypto.NegativeBigLength, "owner"); err != nil {
+ return errors.New("failed to deserialize OwnerKey")
}
if err = p.DraftHash.Deserialize(r); err != nil {
return errors.New("failed to deserialize DraftHash")
@@ -961,8 +961,8 @@ func (p *CRCProposal) DeserializeUnSignedChangeProposalOwner(r io.Reader, versio
if err = p.NewRecipient.Deserialize(r); err != nil {
return errors.New("failed to deserialize Recipient")
}
- if p.NewOwnerPublicKey, err = common.ReadVarBytes(r, crypto.NegativeBigLength, "owner"); err != nil {
- return errors.New("failed to deserialize NewOwnerPublicKey")
+ if p.NewOwnerKey, err = common.ReadVarBytes(r, crypto.NegativeBigLength, "owner"); err != nil {
+ return errors.New("failed to deserialize NewOwnerKey")
}
return nil
}
@@ -975,9 +975,9 @@ func (p *CRCProposal) DeserializeUnsignedRegisterSideChain(r io.Reader, version
return errors.New("[CRCProposal], Category data deserialize failed")
}
- p.OwnerPublicKey, err = common.ReadVarBytes(r, crypto.NegativeBigLength, "owner")
+ p.OwnerKey, err = common.ReadVarBytes(r, crypto.NegativeBigLength, "owner")
if err != nil {
- return errors.New("failed to deserialize OwnerPublicKey")
+ return errors.New("failed to deserialize OwnerKey")
}
if err = p.DraftHash.Deserialize(r); err != nil {
@@ -1006,9 +1006,9 @@ func (p *CRCProposal) DeserializeUnSignedCloseProposal(r io.Reader, version byte
return errors.New("[CRCProposal], Category data deserialize failed")
}
- p.OwnerPublicKey, err = common.ReadVarBytes(r, crypto.NegativeBigLength, "owner")
+ p.OwnerKey, err = common.ReadVarBytes(r, crypto.NegativeBigLength, "owner")
if err != nil {
- return errors.New("failed to deserialize OwnerPublicKey")
+ return errors.New("failed to deserialize OwnerKey")
}
if err = p.DraftHash.Deserialize(r); err != nil {
@@ -1035,9 +1035,9 @@ func (p *CRCProposal) DeserializeUnSignedChangeCustomIDFee(r io.Reader, version
return errors.New("[CRCProposal], Category data deserialize failed")
}
- p.OwnerPublicKey, err = common.ReadVarBytes(r, crypto.NegativeBigLength, "owner")
+ p.OwnerKey, err = common.ReadVarBytes(r, crypto.NegativeBigLength, "owner")
if err != nil {
- return errors.New("failed to deserialize OwnerPublicKey")
+ return errors.New("failed to deserialize OwnerKey")
}
if err = p.DraftHash.Deserialize(r); err != nil {
@@ -1065,9 +1065,9 @@ func (p *CRCProposal) DeserializeUnSignedReceivedCustomID(r io.Reader, version b
return errors.New("[CRCProposal], Category data deserialize failed")
}
- p.OwnerPublicKey, err = common.ReadVarBytes(r, crypto.NegativeBigLength, "owner")
+ p.OwnerKey, err = common.ReadVarBytes(r, crypto.NegativeBigLength, "owner")
if err != nil {
- return errors.New("failed to deserialize OwnerPublicKey")
+ return errors.New("failed to deserialize OwnerKey")
}
if err = p.DraftHash.Deserialize(r); err != nil {
@@ -1109,9 +1109,9 @@ func (p *CRCProposal) DeserializeUnSignedReservedCustomID(r io.Reader, version b
return errors.New("[CRCProposal], Category data deserialize failed")
}
- p.OwnerPublicKey, err = common.ReadVarBytes(r, crypto.NegativeBigLength, "owner")
+ p.OwnerKey, err = common.ReadVarBytes(r, crypto.NegativeBigLength, "owner")
if err != nil {
- return errors.New("failed to deserialize OwnerPublicKey")
+ return errors.New("failed to deserialize OwnerKey")
}
if err = p.DraftHash.Deserialize(r); err != nil {
@@ -1148,9 +1148,9 @@ func (p *CRCProposal) DeserializeUnSignedChangeSecretaryGeneral(r io.Reader, ver
return errors.New("[CRCProposal], Category data deserialize failed")
}
- p.OwnerPublicKey, err = common.ReadVarBytes(r, crypto.NegativeBigLength, "owner")
+ p.OwnerKey, err = common.ReadVarBytes(r, crypto.NegativeBigLength, "owner")
if err != nil {
- return errors.New("failed to deserialize OwnerPublicKey")
+ return errors.New("failed to deserialize OwnerKey")
}
if err = p.DraftHash.Deserialize(r); err != nil {
@@ -1364,7 +1364,7 @@ func (p *CRCProposal) ToProposalInfo(payloadVersion byte) CRCProposalInfo {
info := CRCProposalInfo{
ProposalType: p.ProposalType,
CategoryData: p.CategoryData,
- OwnerPublicKey: p.OwnerPublicKey,
+ OwnerPublicKey: p.OwnerKey,
DraftHash: p.DraftHash,
Budgets: p.Budgets,
Recipient: p.Recipient,
@@ -1375,7 +1375,7 @@ func (p *CRCProposal) ToProposalInfo(payloadVersion byte) CRCProposalInfo {
RateOfCustomIDFee: p.RateOfCustomIDFee,
EIDEffectiveHeight: p.EIDEffectiveHeight,
NewRecipient: p.NewRecipient,
- NewOwnerPublicKey: p.NewOwnerPublicKey,
+ NewOwnerPublicKey: p.NewOwnerKey,
SecretaryGeneralPublicKey: p.SecretaryGeneralPublicKey,
SecretaryGeneralDID: p.SecretaryGeneralDID,
CRCouncilMemberDID: p.CRCouncilMemberDID,
@@ -1473,7 +1473,7 @@ func (p *CRCProposalInfo) Serialize(w io.Writer, version byte) error {
}
if err := common.WriteVarBytes(w, p.OwnerPublicKey); err != nil {
- return errors.New("failed to serialize OwnerPublicKey")
+ return errors.New("failed to serialize OwnerKey")
}
if err := p.DraftHash.Serialize(w); err != nil {
@@ -1535,7 +1535,7 @@ func (p *CRCProposalInfo) Serialize(w io.Writer, version byte) error {
}
if err := common.WriteVarBytes(w, p.NewOwnerPublicKey); err != nil {
- return errors.New("failed to serialize NewOwnerPublicKey")
+ return errors.New("failed to serialize NewOwnerKey")
}
if err := common.WriteVarBytes(w, p.SecretaryGeneralPublicKey); err != nil {
@@ -1574,7 +1574,7 @@ func (p *CRCProposalInfo) Deserialize(r io.Reader, version byte) error {
p.OwnerPublicKey, err = common.ReadVarBytes(r, crypto.NegativeBigLength, "owner")
if err != nil {
- return errors.New("failed to deserialize OwnerPublicKey")
+ return errors.New("failed to deserialize OwnerKey")
}
if err = p.DraftHash.Deserialize(r); err != nil {
@@ -1645,7 +1645,7 @@ func (p *CRCProposalInfo) Deserialize(r io.Reader, version byte) error {
}
if p.NewOwnerPublicKey, err = common.ReadVarBytes(r, crypto.NegativeBigLength, "owner"); err != nil {
- return errors.New("failed to deserialize NewOwnerPublicKey")
+ return errors.New("failed to deserialize NewOwnerKey")
}
p.SecretaryGeneralPublicKey, err = common.ReadVarBytes(r, crypto.NegativeBigLength, "secretarygeneralpublickey")
diff --git a/core/types/payload/crcproposaltracking.go b/core/types/payload/crcproposaltracking.go
index 4834b03de..51a147bc9 100644
--- a/core/types/payload/crcproposaltracking.go
+++ b/core/types/payload/crcproposaltracking.go
@@ -89,11 +89,11 @@ type CRCProposalTracking struct {
// The stage of proposal.
Stage uint8
- // The proposal owner public key.
- OwnerPublicKey []byte
+ // The proposal owner public key or multisign code.
+ OwnerKey []byte
// The new proposal owner public key.
- NewOwnerPublicKey []byte
+ NewOwnerKey []byte
// The signature of proposal owner.
OwnerSignature []byte
@@ -142,12 +142,12 @@ func (p *CRCProposalTracking) SerializeUnsigned(w io.Writer, version byte) error
return errors.New("failed to serialize Stage")
}
- if err := common.WriteVarBytes(w, p.OwnerPublicKey); err != nil {
- return errors.New("failed to serialize OwnerPublicKey")
+ if err := common.WriteVarBytes(w, p.OwnerKey); err != nil {
+ return errors.New("failed to serialize OwnerKey")
}
- if err := common.WriteVarBytes(w, p.NewOwnerPublicKey); err != nil {
- return errors.New("failed to serialize NewOwnerPublicKey")
+ if err := common.WriteVarBytes(w, p.NewOwnerKey); err != nil {
+ return errors.New("failed to serialize NewOwnerKey")
}
return nil
@@ -206,15 +206,14 @@ func (p *CRCProposalTracking) DeserializeUnSigned(r io.Reader, version byte) err
if p.Stage, err = common.ReadUint8(r); err != nil {
return errors.New("failed to deserialize Stage")
}
-
- if p.OwnerPublicKey, err = common.ReadVarBytes(r, crypto.PublicKeyScriptLength,
+ if p.OwnerKey, err = common.ReadVarBytes(r, crypto.PublicKeyScriptLength,
"owner pubkey"); err != nil {
- return errors.New("failed to deserialize OwnerPublicKey")
+ return errors.New("failed to deserialize OwnerKey")
}
- if p.NewOwnerPublicKey, err = common.ReadVarBytes(r, crypto.PublicKeyScriptLength,
+ if p.NewOwnerKey, err = common.ReadVarBytes(r, crypto.PublicKeyScriptLength,
"new owner pubkey"); err != nil {
- return errors.New("failed to deserialize NewOwnerPublicKey")
+ return errors.New("failed to deserialize NewOwnerKey")
}
return nil
diff --git a/core/types/payload/crcproposalwithdraw.go b/core/types/payload/crcproposalwithdraw.go
index f09d50cfc..ab36da41d 100644
--- a/core/types/payload/crcproposalwithdraw.go
+++ b/core/types/payload/crcproposalwithdraw.go
@@ -23,8 +23,8 @@ type CRCProposalWithdraw struct {
// Hash of the proposal to withdrawal ela.
ProposalHash common.Uint256
- // Public key of proposal owner.
- OwnerPublicKey []byte
+ // Public key or multisign code of proposal owner.
+ OwnerKey []byte
// The specified ELA address where the funds will be sent.
Recipient common.Uint168
@@ -63,7 +63,7 @@ func (p *CRCProposalWithdraw) SerializeUnsigned(w io.Writer, version byte) error
return err
}
- if err := common.WriteVarBytes(w, p.OwnerPublicKey); err != nil {
+ if err := common.WriteVarBytes(w, p.OwnerKey); err != nil {
return err
}
@@ -103,7 +103,7 @@ func (p *CRCProposalWithdraw) DeserializeUnsigned(r io.Reader,
if err != nil {
return err
}
- p.OwnerPublicKey = ownerPublicKey
+ p.OwnerKey = ownerPublicKey
if version == CRCProposalWithdrawVersion01 {
if err := p.Recipient.Deserialize(r); err != nil {
diff --git a/core/types/payload/createnft.go b/core/types/payload/createnft.go
index 68f791a8d..3b388afa0 100644
--- a/core/types/payload/createnft.go
+++ b/core/types/payload/createnft.go
@@ -8,12 +8,14 @@ package payload
import (
"bytes"
"errors"
+ "github.com/elastos/Elastos.ELA/crypto"
"io"
"github.com/elastos/Elastos.ELA/common"
)
const CreateNFTVersion byte = 0x00
+const CreateNFTVersion2 byte = 0x01
// CreateNFT defines the transaction of NFT.
type CreateNFT struct {
@@ -26,6 +28,22 @@ type CreateNFT struct {
// genesis block hash of side chain.
GenesisBlockHash common.Uint256
+
+ // the start height of votes
+ StartHeight uint32
+
+ // the end height of votes: start height + lock time.
+ EndHeight uint32
+
+ // the DPoS 2.0 votes.
+ Votes common.Fixed64
+
+ // the DPoS 2.0 vote rights.
+ VoteRights common.Fixed64
+
+ // the votes to the producer, and TargetOwnerPublicKey is the producer's
+ // owner key.
+ TargetOwnerKey []byte
}
func (a *CreateNFT) Data(version byte) []byte {
@@ -58,6 +76,24 @@ func (a *CreateNFT) SerializeUnsigned(w io.Writer, version byte) error {
return errors.New("[CreateNFT], failed to serialize GenesisBlockHash")
}
+ if version >= CreateNFTVersion2 {
+ if err := common.WriteUint32(w, a.StartHeight); err != nil {
+ return errors.New("[CreateNFT], failed to serialize StartHeight")
+ }
+ if err := common.WriteUint32(w, a.EndHeight); err != nil {
+ return errors.New("[CreateNFT], failed to serialize EndHeight")
+ }
+ if err := a.Votes.Serialize(w); err != nil {
+ return errors.New("[CreateNFT], failed to serialize Votes")
+ }
+ if err := a.VoteRights.Serialize(w); err != nil {
+ return errors.New("[CreateNFT], failed to serialize VoteRights")
+ }
+ if err := common.WriteVarBytes(w, a.TargetOwnerKey); err != nil {
+ return errors.New("[CreateNFT], failed to serialize TargetOwnerPublicKey")
+ }
+ }
+
return nil
}
@@ -85,6 +121,25 @@ func (a *CreateNFT) DeserializeUnsigned(r io.Reader, version byte) error {
return errors.New("[CreateNFT], failed to deserialize GenesisBlockHash")
}
+ if version >= CreateNFTVersion2 {
+
+ if a.StartHeight, err = common.ReadUint32(r); err != nil {
+ return errors.New("[CreateNFT], failed to deserialize StartHeight")
+ }
+ if a.EndHeight, err = common.ReadUint32(r); err != nil {
+ return errors.New("[CreateNFT], failed to deserialize EndHeight")
+ }
+ if err := a.Votes.Deserialize(r); err != nil {
+ return errors.New("[CreateNFT], failed to deserialize Votes")
+ }
+ if err := a.VoteRights.Deserialize(r); err != nil {
+ return errors.New("[CreateNFT], failed to deserialize VoteRights")
+ }
+ if a.TargetOwnerKey, err = common.ReadVarBytes(r, crypto.MaxMultiSignCodeLength, "TargetOwnerKey"); err != nil {
+ return errors.New("[CreateNFT], failed to deserialize TargetOwnerKey")
+ }
+ }
+
return nil
}
diff --git a/core/types/payload/crinfo.go b/core/types/payload/crinfo.go
index 11294859e..8e4cdef33 100644
--- a/core/types/payload/crinfo.go
+++ b/core/types/payload/crinfo.go
@@ -17,6 +17,7 @@ import (
const CRInfoVersion byte = 0x00
const CRInfoDIDVersion byte = 0x01
const CRInfoSchnorrVersion byte = 0x02
+const CRInfoMultiSignVersion byte = 0x03
// CRInfo defines the information of CR.
type CRInfo struct {
@@ -27,7 +28,7 @@ type CRInfo struct {
Url string
Location uint64
Signature []byte
-}
+}
func (a *CRInfo) Data(version byte) []byte {
buf := new(bytes.Buffer)
@@ -43,7 +44,7 @@ func (a *CRInfo) Serialize(w io.Writer, version byte) error {
return err
}
- if version != CRInfoSchnorrVersion {
+ if version != CRInfoSchnorrVersion && version != CRInfoMultiSignVersion {
err = common.WriteVarBytes(w, a.Signature)
if err != nil {
return errors.New("[CRInfo], Signature serialize failed")
@@ -54,7 +55,7 @@ func (a *CRInfo) Serialize(w io.Writer, version byte) error {
}
func (a *CRInfo) SerializeUnsigned(w io.Writer, version byte) error {
- if version != CRInfoSchnorrVersion {
+ if version != CRInfoSchnorrVersion && version != CRInfoMultiSignVersion {
err := common.WriteVarBytes(w, a.Code)
if err != nil {
return errors.New("[CRInfo], code serialize failed")
@@ -92,7 +93,7 @@ func (a *CRInfo) Deserialize(r io.Reader, version byte) error {
return err
}
- if version != CRInfoSchnorrVersion {
+ if version != CRInfoSchnorrVersion && version != CRInfoMultiSignVersion {
a.Signature, err = common.ReadVarBytes(r, crypto.MaxSignatureScriptLength, "signature")
if err != nil {
return errors.New("[CRInfo], signature deserialize failed")
@@ -103,7 +104,7 @@ func (a *CRInfo) Deserialize(r io.Reader, version byte) error {
func (a *CRInfo) DeserializeUnsigned(r io.Reader, version byte) error {
var err error
- if version != CRInfoSchnorrVersion {
+ if version != CRInfoSchnorrVersion && version != CRInfoMultiSignVersion {
a.Code, err = common.ReadVarBytes(r, crypto.MaxMultiSignCodeLength, "code")
if err != nil {
return errors.New("[CRInfo], code deserialize failed")
diff --git a/core/types/payload/nextturndposinfo.go b/core/types/payload/nextturndposinfo.go
index ae000a04b..134c679b5 100644
--- a/core/types/payload/nextturndposinfo.go
+++ b/core/types/payload/nextturndposinfo.go
@@ -9,11 +9,13 @@ import (
)
const NextTurnDPOSInfoVersion byte = 0x00
+const NextTurnDPOSInfoVersion2 byte = 0x01
type NextTurnDPOSInfo struct {
- WorkingHeight uint32
- CRPublicKeys [][]byte
- DPOSPublicKeys [][]byte
+ WorkingHeight uint32
+ CRPublicKeys [][]byte
+ DPOSPublicKeys [][]byte
+ CompleteCRPublicKeys [][]byte
hash *common.Uint256
}
@@ -59,6 +61,19 @@ func (n *NextTurnDPOSInfo) SerializeUnsigned(w io.Writer, version byte) error {
return err
}
}
+
+ if version >= NextTurnDPOSInfoVersion2 {
+ if err := common.WriteVarUint(w, uint64(len(n.CompleteCRPublicKeys))); err != nil {
+ return err
+ }
+
+ for _, v := range n.CompleteCRPublicKeys {
+ if err := common.WriteVarBytes(w, v); err != nil {
+ return err
+ }
+ }
+ }
+
return nil
}
@@ -107,6 +122,22 @@ func (n *NextTurnDPOSInfo) DeserializeUnsigned(r io.Reader, version byte) error
}
n.DPOSPublicKeys = append(n.DPOSPublicKeys, DPOSPublicKey)
}
+
+ if version >= NextTurnDPOSInfoVersion2 {
+ if len, err = common.ReadVarUint(r, 0); err != nil {
+ return err
+ }
+ n.CompleteCRPublicKeys = make([][]byte, 0, len)
+ for i := uint64(0); i < len; i++ {
+ var publicKey []byte
+ if publicKey, err = common.ReadVarBytes(r, crypto.COMPRESSEDLEN,
+ "complete crcs"); err != nil {
+ return err
+ }
+ n.CompleteCRPublicKeys = append(n.CompleteCRPublicKeys, publicKey)
+ }
+ }
+
return nil
}
diff --git a/core/types/payload/processproducer.go b/core/types/payload/processproducer.go
index 5c1a1b0a1..1d202d454 100644
--- a/core/types/payload/processproducer.go
+++ b/core/types/payload/processproducer.go
@@ -20,11 +20,12 @@ type ProducerOperation byte
const (
ProcessProducerVersion byte = 0x00
ProcessProducerSchnorrVersion byte = 0x01
+ ProcessMultiCodeVersion byte = 0x02
)
type ProcessProducer struct {
- OwnerPublicKey []byte
- Signature []byte
+ OwnerKey []byte //standard owner public key or multisign ownercode
+ Signature []byte
}
func (a *ProcessProducer) Data(version byte) []byte {
@@ -40,7 +41,7 @@ func (a *ProcessProducer) Serialize(w io.Writer, version byte) error {
if err != nil {
return err
}
- if version != ProcessProducerSchnorrVersion {
+ if version < ProcessProducerSchnorrVersion {
err = common.WriteVarBytes(w, a.Signature)
if err != nil {
return errors.New("[ProcessProducer], signature serialize failed")
@@ -50,7 +51,7 @@ func (a *ProcessProducer) Serialize(w io.Writer, version byte) error {
}
func (a *ProcessProducer) SerializeUnsigned(w io.Writer, version byte) error {
- err := common.WriteVarBytes(w, a.OwnerPublicKey)
+ err := common.WriteVarBytes(w, a.OwnerKey)
if err != nil {
return errors.New("[ProcessProducer], write owner public key failed")
}
@@ -63,7 +64,7 @@ func (a *ProcessProducer) Deserialize(r io.Reader, version byte) error {
if err != nil {
return err
}
- if version != ProcessProducerSchnorrVersion {
+ if version < ProcessProducerSchnorrVersion {
a.Signature, err = common.ReadVarBytes(r, crypto.SignatureLength, "signature")
if err != nil {
return errors.New("[ProcessProducer], signature deserialize failed")
@@ -73,8 +74,9 @@ func (a *ProcessProducer) Deserialize(r io.Reader, version byte) error {
}
func (a *ProcessProducer) DeserializeUnsigned(r io.Reader, version byte) error {
+ readLen := uint32(crypto.MaxMultiSignCodeLength)
var err error
- a.OwnerPublicKey, err = common.ReadVarBytes(r, crypto.NegativeBigLength, "public key")
+ a.OwnerKey, err = common.ReadVarBytes(r, readLen, "public key")
if err != nil {
return errors.New("[ProcessProducer], read owner public key failed")
}
diff --git a/core/types/payload/producerinfo.go b/core/types/payload/producerinfo.go
index d9501360b..802739258 100644
--- a/core/types/payload/producerinfo.go
+++ b/core/types/payload/producerinfo.go
@@ -18,17 +18,20 @@ const (
ProducerInfoVersion byte = 0x00
ProducerInfoDposV2Version byte = 0x01
ProducerInfoSchnorrVersion byte = 0x02
+ ProducerInfoMultiVersion byte = 0x03
)
type ProducerInfo struct {
- OwnerPublicKey []byte
- NodePublicKey []byte
- NickName string
- Url string
- Location uint64
- NetAddress string
- StakeUntil uint32
- Signature []byte
+ //can be standard or multi Code
+ OwnerKey []byte
+ //must standard
+ NodePublicKey []byte
+ NickName string
+ Url string
+ Location uint64
+ NetAddress string
+ StakeUntil uint32
+ Signature []byte
}
func (a *ProducerInfo) Data(version byte) []byte {
@@ -44,7 +47,7 @@ func (a *ProducerInfo) Serialize(w io.Writer, version byte) error {
if err != nil {
return err
}
- if version != ProducerInfoSchnorrVersion {
+ if version < ProducerInfoSchnorrVersion {
err = common.WriteVarBytes(w, a.Signature)
if err != nil {
return errors.New("[ProducerInfo], Signature serialize failed")
@@ -55,9 +58,9 @@ func (a *ProducerInfo) Serialize(w io.Writer, version byte) error {
}
func (a *ProducerInfo) SerializeUnsigned(w io.Writer, version byte) error {
- err := common.WriteVarBytes(w, a.OwnerPublicKey)
+ err := common.WriteVarBytes(w, a.OwnerKey)
if err != nil {
- return errors.New("[ProducerInfo], owner publicKey serialize failed")
+ return errors.New("[ProducerInfo], owner Key serialize failed")
}
err = common.WriteVarBytes(w, a.NodePublicKey)
@@ -99,7 +102,7 @@ func (a *ProducerInfo) Deserialize(r io.Reader, version byte) error {
if err != nil {
return err
}
- if version != ProducerInfoSchnorrVersion {
+ if version < ProducerInfoSchnorrVersion {
a.Signature, err = common.ReadVarBytes(r, crypto.SignatureLength, "signature")
if err != nil {
return errors.New("[ProducerInfo], signature deserialize failed")
@@ -109,13 +112,14 @@ func (a *ProducerInfo) Deserialize(r io.Reader, version byte) error {
}
func (a *ProducerInfo) DeserializeUnsigned(r io.Reader, version byte) error {
+ readLen := uint32(crypto.MaxMultiSignCodeLength)
var err error
- a.OwnerPublicKey, err = common.ReadVarBytes(r, crypto.NegativeBigLength, "own public key")
+ a.OwnerKey, err = common.ReadVarBytes(r, readLen, "owner public key or owner multisign code")
if err != nil {
return errors.New("[ProducerInfo], owner publicKey deserialize failed")
}
- a.NodePublicKey, err = common.ReadVarBytes(r, crypto.NegativeBigLength, "node public key")
+ a.NodePublicKey, err = common.ReadVarBytes(r, readLen, "node public key")
if err != nil {
return errors.New("[ProducerInfo], node publicKey deserialize failed")
}
diff --git a/core/types/payload/unregistercr.go b/core/types/payload/unregistercr.go
index bf1dcca90..27f9d1b2c 100644
--- a/core/types/payload/unregistercr.go
+++ b/core/types/payload/unregistercr.go
@@ -16,6 +16,7 @@ import (
const UnregisterCRVersion byte = 0x00
const UnregisterCRSchnorrVersion byte = 0x01
+const UnregisterCRMultiVersion byte = 0x02
type UnregisterCR struct {
CID common.Uint168
@@ -36,7 +37,7 @@ func (a *UnregisterCR) Serialize(w io.Writer, version byte) error {
return err
}
- if version != UnregisterCRSchnorrVersion {
+ if version != UnregisterCRSchnorrVersion && version != UnregisterCRMultiVersion {
err = common.WriteVarBytes(w, a.Signature)
if err != nil {
return errors.New("[UnregisterCR], Signature serialize failed")
@@ -59,7 +60,7 @@ func (a *UnregisterCR) Deserialize(r io.Reader, version byte) error {
return err
}
- if version != UnregisterCRSchnorrVersion {
+ if version != UnregisterCRSchnorrVersion && version != UnregisterCRMultiVersion {
a.Signature, err = common.ReadVarBytes(r, crypto.MaxSignatureScriptLength, "signature")
if err != nil {
return errors.New("[UnregisterCR], signature deserialize failed")
diff --git a/cr/state/checkpoint.go b/cr/state/checkpoint.go
index 7d2829e0b..b6a72b33f 100644
--- a/cr/state/checkpoint.go
+++ b/cr/state/checkpoint.go
@@ -27,7 +27,7 @@ const (
checkpointHeight = uint32(720)
// EffectiveHeight defines interval to change src file to default file.
- EffectiveHeight = uint32(7)
+ EffectiveHeight = uint32(720)
)
// Checkpoint hold all CR related states to recover from scratch.
@@ -166,6 +166,10 @@ func (c *Checkpoint) OnInit() {
c.committee.Recover(c)
}
+func (c *Checkpoint) SaveStartHeight() uint32 {
+ return c.committee.Params.CRConfiguration.CRVotingStartHeight
+}
+
func (c *Checkpoint) StartHeight() uint32 {
return c.committee.Params.CRConfiguration.CRVotingStartHeight
}
diff --git a/cr/state/proposalmanager.go b/cr/state/proposalmanager.go
index e344e8c44..29f92add4 100644
--- a/cr/state/proposalmanager.go
+++ b/cr/state/proposalmanager.go
@@ -652,7 +652,7 @@ func (p *ProposalManager) registerProposal(tx interfaces.Transaction,
FinalPaymentStatus: false,
TrackingCount: 0,
TerminatedHeight: 0,
- ProposalOwner: proposal.OwnerPublicKey,
+ ProposalOwner: proposal.OwnerKey,
Recipient: proposal.Recipient,
}
crCouncilMemberDID := proposal.CRCouncilMemberDID
@@ -862,7 +862,7 @@ func (p *ProposalManager) proposalTracking(tx interfaces.Transaction,
}
proposalState.BudgetsStatus[proposalTracking.Stage] = Rejected
case payload.ChangeOwner:
- proposalState.ProposalOwner = proposalTracking.NewOwnerPublicKey
+ proposalState.ProposalOwner = proposalTracking.NewOwnerKey
case payload.Terminated:
proposalState.TerminatedHeight = height
proposalState.Status = Terminated
diff --git a/cr/state/proposalmanager_test.go b/cr/state/proposalmanager_test.go
index e9c466fe8..e4dce0d47 100644
--- a/cr/state/proposalmanager_test.go
+++ b/cr/state/proposalmanager_test.go
@@ -75,7 +75,7 @@ func randomProposalState() *ProposalState {
func randomCRCProposal() *payload.CRCProposal {
return &payload.CRCProposal{
ProposalType: payload.CRCProposalType(rand.Int31n(6)),
- OwnerPublicKey: randomBytes(33),
+ OwnerKey: randomBytes(33),
CRCouncilMemberDID: *randomUint168(),
DraftHash: *randomUint256(),
Budgets: createBudgets(5),
diff --git a/cr/state/state.go b/cr/state/state.go
index 506973302..418f0c088 100644
--- a/cr/state/state.go
+++ b/cr/state/state.go
@@ -252,8 +252,10 @@ func (s *State) registerCR(tx interfaces.Transaction, height uint32) {
info := tx.Payload().(*payload.CRInfo)
nickname := info.NickName
var code string
- if tx.PayloadVersion() == payload.CRInfoSchnorrVersion {
+ if tx.PayloadVersion() == payload.CRInfoSchnorrVersion ||
+ tx.PayloadVersion() == payload.CRInfoMultiSignVersion {
code = common.BytesToHexString(tx.Programs()[0].Code)
+ info.Code = tx.Programs()[0].Code
} else {
code = common.BytesToHexString(info.Code)
}
diff --git a/crypto/crypto.go b/crypto/crypto.go
index fb2849088..37521e0d6 100644
--- a/crypto/crypto.go
+++ b/crypto/crypto.go
@@ -17,6 +17,7 @@ import (
"sort"
"github.com/elastos/Elastos.ELA/common"
+ "github.com/elastos/Elastos.ELA/core/contract/program"
"github.com/elastos/Elastos.ELA/crypto/ecies"
)
@@ -244,3 +245,62 @@ func Equal(e1 *PublicKey, e2 *PublicKey) bool {
}
return true
}
+
+func CheckMultiSigSignatures(program program.Program, data []byte) error {
+ code := program.Code
+ // Get N parameter
+ n := int(code[len(code)-2]) - PUSH1 + 1
+ // Get M parameter
+ m := int(code[0]) - PUSH1 + 1
+ if m < 1 || m > n {
+ return errors.New("invalid multi sign script code")
+ }
+ publicKeys, err := ParseMultisigScript(code)
+ if err != nil {
+ return err
+ }
+
+ return VerifyMultisigSignatures(m, n, publicKeys, program.Parameter, data)
+}
+func VerifyMultisigSignatures(m, n int, publicKeys [][]byte, signatures, data []byte) error {
+ if len(publicKeys) != n {
+ return errors.New("invalid multi sign public key script count")
+ }
+ if len(signatures)%SignatureScriptLength != 0 {
+ return errors.New("invalid multi sign signatures, length not match")
+ }
+ if len(signatures)/SignatureScriptLength < m {
+ return errors.New("invalid signatures, not enough signatures")
+ }
+ if len(signatures)/SignatureScriptLength > n {
+ return errors.New("invalid signatures, too many signatures")
+ }
+
+ var verified = make(map[common.Uint256]struct{})
+ for i := 0; i < len(signatures); i += SignatureScriptLength {
+ // Remove length byte
+ sign := signatures[i : i+SignatureScriptLength][1:]
+ // Match public key with signature
+ for _, publicKey := range publicKeys {
+ pubKey, err := DecodePoint(publicKey[1:])
+ if err != nil {
+ return err
+ }
+ err = Verify(*pubKey, data, sign)
+ if err == nil {
+ hash := sha256.Sum256(publicKey)
+ if _, ok := verified[hash]; ok {
+ return errors.New("duplicated signatures")
+ }
+ verified[hash] = struct{}{}
+ break // back to public keys loop
+ }
+ }
+ }
+ // Check signatures count
+ if len(verified) < m {
+ return errors.New("matched signatures not enough")
+ }
+
+ return nil
+}
diff --git a/docs/release-notes/release-notes-0.9.9.md b/docs/release-notes/release-notes-0.9.9.md
new file mode 100644
index 000000000..9845861f6
--- /dev/null
+++ b/docs/release-notes/release-notes-0.9.9.md
@@ -0,0 +1,133 @@
+Elastos.ELA version 0.9.9 is now available from:
+
+
+
+This is a new major version release.
+
+Please report bugs using the issue tracker at GitHub:
+
+
+
+How to Upgrade
+==============
+
+If you are running version release_v0.9.8.2 and before, you should shut it down
+and wait until it has completely closed, then just copy over `ela`(on Linux)
+and obtain the sponsors file to place it in the working directory.
+
+However, as usual, config, keystore and chaindata files are compatible.
+
+Compatibility
+==============
+
+Elastos.ELA is supported and extensively tested on operating systems
+using the Linux kernel. It is not recommended to use Elastos.ELA on
+unsupported systems.
+
+Elastos.ELA should also work on most other Unix-like systems but is not
+as frequently tested on them.
+
+As previously-supported CPU platforms, this release's pre-compiled
+distribution provides binaries for the x86_64 platform.
+
+Notable changes
+===============
+
+1. Modify the view reset recovery mechanism in DPOS consensus to a view catching-up mechanism.
+2. Open evidence transactions for proposal misconduct and voting misconduct.
+3. Fix and optimize the fork reorganization issues under POW and DPOS.
+
+0.9.9 change log
+=================
+
+### Bug Fixes
+
+* **bpos:** fixed an issue of real withdraw transaction ([6bc854d](https://github.com/elastos/Elastos.ELA/commit/6bc854dfb5e9d2680c8293061578bfa09969a68e))
+* **bpos:** modify to create new version NextTrunDPoSInfo tx correctly ([8c50cf8](https://github.com/elastos/Elastos.ELA/commit/8c50cf89002a6ed94bf25c8c3cf4b67ec4586d5b))
+* **bpos:** modity to deserialize nextTurnDPoSInfo payload correctly ([d14512e](https://github.com/elastos/Elastos.ELA/commit/d14512e2add518030076064be228d80228619529))
+* **cli:** update ela version information ([bfeb412](https://github.com/elastos/Elastos.ELA/commit/bfeb4120defed420f85841ba1cae0ecdda87ce10))
+* **dpos2.0:** change revertToDPoS script attribute to nonce ([c72e123](https://github.com/elastos/Elastos.ELA/commit/c72e123cc02dd2d70f504b14fcd6b7132d7cf0a4))
+* **dpos:** change view when offset different ([92e07e6](https://github.com/elastos/Elastos.ELA/commit/92e07e6aa32870162b9ade553dc29d6b61cc2c12))
+* **dpos:** fixed an issue of CheckBlockContext ([6d62f4b](https://github.com/elastos/Elastos.ELA/commit/6d62f4b1514f3f672cbe2ec6b51bd6cacbd9c50a))
+* **dpos:** get block with PID ([7ddf3e3](https://github.com/elastos/Elastos.ELA/commit/7ddf3e32e46118729194ff52dc8f6812818d184e))
+* **dpos:** last irreversible height is not allowed to rollback ([e2bbc56](https://github.com/elastos/Elastos.ELA/commit/e2bbc563d78451d8bc9a961f4ec1bcf25e7c80c7))
+* **dpos:** modify to recover view offset correctly ([31f6522](https://github.com/elastos/Elastos.ELA/commit/31f652289900c763028954760890eeb6075e93ab))
+* **dpos:** not reset LastArbiters ([3b37403](https://github.com/elastos/Elastos.ELA/commit/3b37403ed5609afa14e30d36317d5f6aaf92f45f))
+* **dpos:** record last dpos rewards by history ([cf2aef4](https://github.com/elastos/Elastos.ELA/commit/cf2aef49048810b2f60b18264582069c91e30aec))
+* **dpos:** remove history by real changes ([bbf89ab](https://github.com/elastos/Elastos.ELA/commit/bbf89ab7f5e04981bb644702eb723a5210ce8c6d))
+* **dpos:** reocrd last dpos rewards by history ([f300d17](https://github.com/elastos/Elastos.ELA/commit/f300d17bf9c1208a7798b36066b9b7a04fab1abc))
+* **nft:** change CreateNFTTransaction err msg ([d11565a](https://github.com/elastos/Elastos.ELA/commit/d11565a5f40d641a6209f1c24c210b7f2cf0aa26))
+* **nft:** change NFTID to ReferKey ([2b70cd7](https://github.com/elastos/Elastos.ELA/commit/2b70cd713ce3f1f73f4a751b962face875fc7fe0))
+* **nft:** change ownerkey to hash function ([4188d68](https://github.com/elastos/Elastos.ELA/commit/4188d68c02e390880517535630ef5cdbd78cadd3))
+* **nft:** end height need to be equal to LockTime ([f40482b](https://github.com/elastos/Elastos.ELA/commit/f40482b540c96cd4fe05181421422a11fd1b6008))
+* **nft:** modify to show NFT transaction correctly ([df8bc65](https://github.com/elastos/Elastos.ELA/commit/df8bc655204e78179303241012d438008ec6ba5c))
+* **nft:** more than 720 blocks can reorganize under pow ([798658d](https://github.com/elastos/Elastos.ELA/commit/798658d4599347d348d77766f79f3f51826a0ca4))
+* **nft:** more than 720 blocks can reorganize under pow ([9954c12](https://github.com/elastos/Elastos.ELA/commit/9954c12adacb251ee6f1ba72152c4d3f4f412dfb))
+* **nft:** N of multisign register producer tx can not over 10 ([897307d](https://github.com/elastos/Elastos.ELA/commit/897307df69183107312844f9fd9090f07d996da6))
+* **pow:** prevent record sponsor tx from tx pool ([e1f7ec8](https://github.com/elastos/Elastos.ELA/commit/e1f7ec8b2a0d72a5ba2b36c658795cc737716215))
+* **test:** let tests pass ([64ed9d5](https://github.com/elastos/Elastos.ELA/commit/64ed9d5720cc6887edddd9c68998161f6714e60f))
+
+
+### Features
+
+* **bpos:** add default view offset ([47041ac](https://github.com/elastos/Elastos.ELA/commit/47041ac31e981bac31501bae415d154afec8a7cd))
+* **bpos:** add MultiExchangeVotesStartHeight ([653cd1f](https://github.com/elastos/Elastos.ELA/commit/653cd1fa8775b5e18c3e24d243c01c2f73fb6f87))
+* **bpos:** adjust change view logic and revert to pow logic ([be9dfa5](https://github.com/elastos/Elastos.ELA/commit/be9dfa5853de800a763dd6fde5a5915f98a2ed80))
+* **bpos:** adjust the judgment rules of IllegalProposal and IllegalVotes ([43987df](https://github.com/elastos/Elastos.ELA/commit/43987dfbbb6613f89ddde9ce51c550ed489e69d3))
+* **bpos:** calculate offset by arbiters count ([71bfc5b](https://github.com/elastos/Elastos.ELA/commit/71bfc5ba4c6b04d3a04394d022a5922583e7a074))
+* **bpos:** change arbiters count from float64 to int ([be66579](https://github.com/elastos/Elastos.ELA/commit/be665791dab110810d167e9f601c9f9db054009f))
+* **bpos:** change the rule of view offset ([04d5814](https://github.com/elastos/Elastos.ELA/commit/04d5814361b8a18bf9b2b5d66705f86dd93ca398))
+* **bpos:** create IllegalProposal and IllegalVote evidence after ChangeViewV1Height ([1997779](https://github.com/elastos/Elastos.ELA/commit/1997779cc29d5484b13ea5f2a6340b52b58f1530))
+* **bpos:** instead illegalV2Height with ChangeViewV1Height ([aee7071](https://github.com/elastos/Elastos.ELA/commit/aee7071f9cc3d331db9f38e35c072c745b42f4bf))
+* **bpos:** instead RevertToPOWV1Height with new change view height ([3a1935e](https://github.com/elastos/Elastos.ELA/commit/3a1935e7739f7051470d642afbbd2386ba408b82))
+* **bpos:** modify to save checkpoints file correctly ([b9e2cec](https://github.com/elastos/Elastos.ELA/commit/b9e2cec537e1c352b8bf898d98eca3f927ec9ab0))
+* **bpos:** remove exception data processing logic ([164655b](https://github.com/elastos/Elastos.ELA/commit/164655be7b28aeb3829b46dffdc267e927b4d069))
+* **bpos:** remove recover consensus logic ([642f4c7](https://github.com/elastos/Elastos.ELA/commit/642f4c72bf1f775d712ae7a6a1ed1fd12b1a9e2d))
+* **bpos:** remove recover view offset logic after ChangeViewV1Height ([a840a84](https://github.com/elastos/Elastos.ELA/commit/a840a84a7e1f95cb330925c80c1f9cf9f1a0697e))
+* **bpos:** vote proposal after change view ([dd09828](https://github.com/elastos/Elastos.ELA/commit/dd09828db0f03252620684552f5cebd0469bbf76))
+* **checkpoints:** adjust logic of checkpoints ([455f0ea](https://github.com/elastos/Elastos.ELA/commit/455f0ea18692adf5ee473c91866872001f656835))
+* **checkpoints:** change the start height of DPoS checkpoints to be same as CR ([7def4a2](https://github.com/elastos/Elastos.ELA/commit/7def4a2a3b664e958d9f53493e2bd3e1c1f5da2c))
+* **dex:** add NextTurnDPOSPayloadInfoV2 ([e625c9d](https://github.com/elastos/Elastos.ELA/commit/e625c9d18fd6557b72cbf628ed658f6dce91d014))
+* **dex:** modify NextTurn transaction for dex ([55eac2b](https://github.com/elastos/Elastos.ELA/commit/55eac2b35e46ce434d5d17ecf451c780024d6d2d))
+* **dpos:** add change view related log ([b3130ad](https://github.com/elastos/Elastos.ELA/commit/b3130ad89fab5bc41d1834ca3fe4cc5b9773455a))
+* **dpos:** allow illegla evidences into txpool ([e741ce1](https://github.com/elastos/Elastos.ELA/commit/e741ce1ed699443722561145aa110e2baa849f44))
+* **dpos:** generate block with sponsor tx ([f8f236a](https://github.com/elastos/Elastos.ELA/commit/f8f236a83450bfaa09df0859a7a6b513cef974b5))
+* **dpos:** get block from block cache first ([01563e0](https://github.com/elastos/Elastos.ELA/commit/01563e0e9d001863db6a17252a7b8835b51fc79e))
+* **dpos:** record consensus current height ([ee22aca](https://github.com/elastos/Elastos.ELA/commit/ee22acabc00d6d505f15d9a484943453d7300dbb))
+* **dpos:** remove height version check of illegal proposal ([69870ad](https://github.com/elastos/Elastos.ELA/commit/69870ad92cf0a56ea4e7b92ce62283eb320db829))
+* **dpos:** remove reset view logic ([e50f53e](https://github.com/elastos/Elastos.ELA/commit/e50f53e49d7fe96af292cef23bcaadf760e8f67b))
+* **dpos:** set default value for testnet ([5778cfd](https://github.com/elastos/Elastos.ELA/commit/5778cfdbe65c0477169d606c98737a261daa4165))
+* **dpos:** set value of ChangeViewV1Height ([b54bf13](https://github.com/elastos/Elastos.ELA/commit/b54bf1394a25f691dc1f6f2c79e20527746e4f79))
+* **dpos:** update change view duration ([d62182e](https://github.com/elastos/Elastos.ELA/commit/d62182e2aa660688c329ea9d2603f7ca466f8616))
+* **dpos:** update dependency ([e17507c](https://github.com/elastos/Elastos.ELA/commit/e17507c7cb1640055ce6ec89bb0e3fec70f798be))
+* **dpos:** update illegal votes logic ([22731b6](https://github.com/elastos/Elastos.ELA/commit/22731b6c12aa34f680bb126a180457c9bdac8e71))
+* **dpos:** update max tx per block ([2471e4d](https://github.com/elastos/Elastos.ELA/commit/2471e4d369fe8f9dd48f11bc4c569a8998e61697))
+* **dpos:** update process proposal logic ([d92df7c](https://github.com/elastos/Elastos.ELA/commit/d92df7c0b6e5041bf5df7e35cc9599d76322a08b))
+* **go:** update go version to 1.20 ([0689eb6](https://github.com/elastos/Elastos.ELA/commit/0689eb6e5253499c5b9c869b7df937b7f58997a2))
+* **multi:** add register_cr_multi_tx.lua ([61db42c](https://github.com/elastos/Elastos.ELA/commit/61db42cb2b6beef82d1b90a0db2faeb1a9c6cf21))
+* **multi:** add unregister_cr_multi_tx.lua ([5f5fa41](https://github.com/elastos/Elastos.ELA/commit/5f5fa413a3297d7c3f26b3517abc110aece11846))
+* **multi:** add update_cr_multi_tx.lua ([0a9f178](https://github.com/elastos/Elastos.ELA/commit/0a9f178488b0ee660f6cbb6eab5fa67f89c9bc31))
+* **multiaddr:** before VotesSchnorrStartHeight every ExchangeVotesTransaction program can not be schnorr ([06d6b1c](https://github.com/elastos/Elastos.ELA/commit/06d6b1ce05224f797fa2e36b622d8b6c76db2b55))
+* **multiaddr:** exchange vote add multi programs ([f38e6f2](https://github.com/elastos/Elastos.ELA/commit/f38e6f298c67b032f75b09ce255a1a9577e683e2))
+* **multiaddr:** ExchangeVotesTransaction len(t.Programs()) must be 1 in CheckOutputSingleInput ([5d836c2](https://github.com/elastos/Elastos.ELA/commit/5d836c28898ff75ebea416be77682fbf1a64c082))
+* **multiaddr:** support multi-address exchange votes transaction ([dd9bf87](https://github.com/elastos/Elastos.ELA/commit/dd9bf87cec0834c79968b8005b9031e6b813dd1d))
+* **multi:** modify to create multi-sign register CR tx correctly ([e3fc737](https://github.com/elastos/Elastos.ELA/commit/e3fc7379435c2323e68bbcb0261b3f77bcf2d5ad))
+* **multi:** register CR tx with multi sign payload is not allowed before NFTStartHeight ([00cc9bd](https://github.com/elastos/Elastos.ELA/commit/00cc9bdc1c016ba817f5e3031f1960ac1c65fb51))
+* **multi:** support the creation of CR related multi-sign transactions ([3e18862](https://github.com/elastos/Elastos.ELA/commit/3e18862d4f1ab8121b2c6353d3a1f80a67299439))
+* **nft:** add deailed votes infromation into NFT tx payload ([e904fc4](https://github.com/elastos/Elastos.ELA/commit/e904fc40a4bf558c005a351d949568a218d902c0))
+* **nft:** add genesis block hash to createNFT tx payload ([5ad5e3e](https://github.com/elastos/Elastos.ELA/commit/5ad5e3ef62e21cc2b0c9cdd6609941baaaa2f85c))
+* **nft:** after NFTV2StartHeight create NFT tx with payload version 0 is invalid ([fad35aa](https://github.com/elastos/Elastos.ELA/commit/fad35aabe17e0df39cf747fa1bb50c897c7aee5b))
+* **nft:** change deposit ([761ab1d](https://github.com/elastos/Elastos.ELA/commit/761ab1d384b1c897b020334a4af5542a1bb97aae))
+* **nft:** check if the NFT of DestroyNFT transaction exist ([e68b9ad](https://github.com/elastos/Elastos.ELA/commit/e68b9ad37d99ff9ce655ca0c54ee05465f8cab20))
+* **nft:** modify to check and process votes rights correctly ([625fd15](https://github.com/elastos/Elastos.ELA/commit/625fd1559d94c5fdb994818a62f738c2716a75d1))
+* **nft:** modify to check stake address of CreateNFT transaction correctly ([379e9f4](https://github.com/elastos/Elastos.ELA/commit/379e9f40a8119f9388d06c5f1323256928ce62af))
+* **nft:** modify to show CreateNFT transaction payload correctly ([33f1c70](https://github.com/elastos/Elastos.ELA/commit/33f1c70e5c8ea3e70ce9fcbce6fa355900694cd9))
+* **nft:** producer tx multisign finish test finish ([20cb384](https://github.com/elastos/Elastos.ELA/commit/20cb384e865058c6ec5ebf1fa6a2331968be649d))
+* **nft:** producer tx lua add multicode support ([ae4b0d3](https://github.com/elastos/Elastos.ELA/commit/ae4b0d3884ab3e6dbd0c8a1796389cc7ca8c9c4b))
+* **nft:** recored the relationship between NFT ID and genesis block hash ([16bff61](https://github.com/elastos/Elastos.ELA/commit/16bff6154ca742bd1b3cfc8acceb09893878efda))
+* **nft:** remove the relationship between id and genesis block hash when NFT destroyed ([82dfad1](https://github.com/elastos/Elastos.ELA/commit/82dfad141bdc53443ffdc19faf57d9bd0413413e))
+* **nft:** rename from ownerPublickey to OwnerKey ([c0399e1](https://github.com/elastos/Elastos.ELA/commit/c0399e1bf2856334412552a5f5653efc6eb19ce8))
+* **nft:** rpc return continue use OwnerPublicKey for exchange ([0163246](https://github.com/elastos/Elastos.ELA/commit/0163246eee919a2243b03022245b62904a20dd73))
+* **nft:** update create_nft.lua ([124f91e](https://github.com/elastos/Elastos.ELA/commit/124f91eb75af2aa5239e001d245eb452fda5b420))
+* **schnorr:** remove activate producer schnorr test ([8ade256](https://github.com/elastos/Elastos.ELA/commit/8ade25611208f8ff0aa3aa9ad727a4dd0d0a039f))
+* **schnorr:** remove schnorr payload version from activate tx ([202a84b](https://github.com/elastos/Elastos.ELA/commit/202a84bf4aaa64add2279d776622c8c27c21de7b))
\ No newline at end of file
diff --git a/dpos/arbitrator.go b/dpos/arbitrator.go
index f4b42b4af..92a3851a6 100644
--- a/dpos/arbitrator.go
+++ b/dpos/arbitrator.go
@@ -54,17 +54,17 @@ type Arbitrator struct {
}
type PeerInfo struct {
- OwnerPublicKey string `json:"ownerpublickey"`
- NodePublicKey string `json:"nodepublickey"`
- IP string `json:"ip"`
- ConnState string `json:"connstate"`
+ OwnerKey string `json:"ownerpublickey"`
+ NodePublicKey string `json:"nodepublickey"`
+ IP string `json:"ip"`
+ ConnState string `json:"connstate"`
}
func (p *PeerInfo) String() string {
return fmt.Sprint("PeerInfo: {\n\t",
"IP: ", p.IP, "\n\t",
"ConnState: ", p.ConnState, "\n\t",
- "OwnerPublicKey: ", p.OwnerPublicKey, "\n\t",
+ "OwnerKey: ", p.OwnerKey, "\n\t",
"NodePublicKey: ", p.NodePublicKey, "\n\t",
"}\n")
}
@@ -137,7 +137,7 @@ func (a *Arbitrator) dumpPeersInfo() {
continue
}
peerInfo := PeerInfo{
- OwnerPublicKey: common.BytesToHexString(
+ OwnerKey: common.BytesToHexString(
producer.GetOwnerPublicKey()),
NodePublicKey: common.BytesToHexString(
producer.GetNodePublicKey()),
@@ -204,7 +204,15 @@ func (a *Arbitrator) OnBlockReceived(b *types.Block, confirmed bool) {
if b.Height >= a.cfg.ChainParams.DPoSConfiguration.RevertToPOWStartHeight {
lastBlockTimestamp := int64(a.cfg.Arbitrators.GetLastBlockTimestamp())
localTimestamp := a.cfg.Chain.TimeSource.AdjustedTime().Unix()
- if localTimestamp-lastBlockTimestamp >= a.cfg.ChainParams.DPoSConfiguration.StopConfirmBlockTime {
+
+ var stopConfirmTime int64
+ if b.Height < a.cfg.ChainParams.DPoSConfiguration.ChangeViewV1Height {
+ stopConfirmTime = a.cfg.ChainParams.DPoSConfiguration.StopConfirmBlockTime
+ } else {
+ stopConfirmTime = a.cfg.ChainParams.DPoSConfiguration.StopConfirmBlockTimeV1
+ }
+
+ if localTimestamp-lastBlockTimestamp >= stopConfirmTime {
return
}
}
@@ -281,7 +289,7 @@ func NewArbitrator(account account.Account, cfg Config) (*Arbitrator, error) {
consensus := manager.NewConsensus(dposManager,
cfg.ChainParams.DPoSConfiguration.SignTolerance,
- dposHandlerSwitch)
+ dposHandlerSwitch, cfg.ChainParams.DPoSConfiguration.ChangeViewV1Height)
proposalDispatcher, illegalMonitor := manager.NewDispatcherAndIllegalMonitor(
manager.ProposalDispatcherConfig{
EventMonitor: eventMonitor,
diff --git a/dpos/manager/consensus.go b/dpos/manager/consensus.go
index 3b4f35cd1..8d2fbea1a 100644
--- a/dpos/manager/consensus.go
+++ b/dpos/manager/consensus.go
@@ -18,9 +18,13 @@ import (
const (
consensusReady = iota
consensusRunning
+
+ DefaultViewOffset = 0
)
type Consensus struct {
+ currentHeight uint32
+ finishedHeight uint32
consensusStatus uint32
viewOffset uint32
@@ -29,16 +33,17 @@ type Consensus struct {
}
func NewConsensus(manager *DPOSManager, tolerance time.Duration,
- viewListener ViewListener) *Consensus {
+ viewListener ViewListener, changeViewV1Height uint32) *Consensus {
c := &Consensus{
consensusStatus: consensusReady,
- viewOffset: 0,
+ viewOffset: DefaultViewOffset,
manager: manager,
currentView: view{
- publicKey: manager.publicKey,
- signTolerance: tolerance,
- listener: viewListener,
- arbitrators: manager.arbitrators,
+ publicKey: manager.publicKey,
+ signTolerance: tolerance,
+ listener: viewListener,
+ arbitrators: manager.arbitrators,
+ changeViewV1Height: changeViewV1Height,
},
}
@@ -58,7 +63,8 @@ func (c *Consensus) SetRunning() {
c.resetViewOffset()
}
-func (c *Consensus) SetReady() {
+func (c *Consensus) SetReady(height uint32) {
+ c.finishedHeight = height
c.consensusStatus = consensusReady
c.resetViewOffset()
}
@@ -83,6 +89,8 @@ func (c *Consensus) StartConsensus(b *types.Block) {
log.Info("[StartConsensus] consensus start")
defer log.Info("[StartConsensus] consensus end")
+ c.currentHeight = b.Height
+
now := c.manager.timeSource.AdjustedTime()
c.manager.GetBlockCache().Reset(b)
c.SetRunning()
@@ -108,12 +116,22 @@ func (c *Consensus) ProcessBlock(b *types.Block) {
}
func (c *Consensus) ChangeView() {
- c.currentView.ChangeView(&c.viewOffset, c.manager.timeSource.AdjustedTime())
+ if c.currentHeight < c.manager.chainParams.DPoSConfiguration.ChangeViewV1Height {
+ c.currentView.ChangeView(&c.viewOffset, c.manager.timeSource.AdjustedTime())
+ } else {
+ c.currentView.ChangeViewV1(&c.viewOffset, c.manager.timeSource.AdjustedTime())
+ }
+
}
func (c *Consensus) TryChangeView() bool {
if c.IsRunning() {
- return c.currentView.TryChangeView(&c.viewOffset, c.manager.timeSource.AdjustedTime())
+ if c.currentHeight < c.manager.chainParams.DPoSConfiguration.ChangeViewV1Height {
+ return c.currentView.TryChangeView(&c.viewOffset, c.manager.timeSource.AdjustedTime())
+ } else {
+ return c.currentView.TryChangeViewV1(&c.viewOffset, c.manager.timeSource.AdjustedTime())
+ }
+
}
return false
}
@@ -135,5 +153,5 @@ func (c *Consensus) RecoverFromConsensusStatus(status *msg.ConsensusStatus) erro
}
func (c *Consensus) resetViewOffset() {
- c.viewOffset = 0
+ c.viewOffset = DefaultViewOffset
}
diff --git a/dpos/manager/dposmanager.go b/dpos/manager/dposmanager.go
index ce020f9f3..d81f4373d 100644
--- a/dpos/manager/dposmanager.go
+++ b/dpos/manager/dposmanager.go
@@ -248,10 +248,13 @@ func (d *DPOSManager) OnProposalReceived(id dpeer.PID, p *payload.DPOSProposal)
if d.consensus.viewOffset != 0 && d.arbitrators.HasArbitersHalfMinorityCount(count) {
log.Info("[OnProposalReceived] has minority not handled" +
" proposals, need recover")
- if d.recoverAbnormalState() {
- log.Info("[OnProposalReceived] recover start")
- } else {
- log.Error("[OnProposalReceived] has no active peers recover failed")
+
+ if d.consensus.finishedHeight < d.chainParams.DPoSConfiguration.ChangeViewV1Height {
+ if d.recoverAbnormalState() {
+ log.Info("[OnProposalReceived] recover start")
+ } else {
+ log.Error("[OnProposalReceived] has no active peers recover failed")
+ }
}
}
}
@@ -328,10 +331,20 @@ func (d *DPOSManager) isBlockExist(blockHash common.Uint256) bool {
return block != nil
}
+func (d *DPOSManager) GetBlockByHash(blockHash common.Uint256) (*types.Block, error) {
+ return d.getBlock(blockHash)
+}
+
func (d *DPOSManager) OnGetBlock(id dpeer.PID, blockHash common.Uint256) {
if !d.isCurrentArbiter() {
return
}
+
+ if block, ok := d.GetBlockCache().TryGetValue(blockHash); ok {
+ go d.network.SendMessageToPeer(id, msg.NewBlock(block))
+ return
+ }
+
if block, err := d.getBlock(blockHash); err == nil {
go d.network.SendMessageToPeer(id, msg.NewBlock(block))
}
@@ -353,6 +366,8 @@ func (d *DPOSManager) OnResponseBlocks(id dpeer.PID, blockConfirms []*types.Dpos
}
func (d *DPOSManager) OnRequestConsensus(id dpeer.PID, height uint32) {
+ // only use reset view
+ return
if !d.isCurrentArbiter() {
return
}
@@ -397,6 +412,8 @@ func (d *DPOSManager) OnRecoverTimeout() {
}
func (d *DPOSManager) recoverAbnormalState() bool {
+ // only use reset view
+ return false
if d.recoverStarted {
return false
}
@@ -436,6 +453,8 @@ func (d *DPOSManager) recoverAbnormalState() bool {
}
func (d *DPOSManager) DoRecover() {
+ // only use reset view
+ return
if d.consensus.viewOffset == 0 {
log.Info("no need to recover view offset")
return
@@ -503,6 +522,10 @@ func (d *DPOSManager) OnChangeView() {
log.Info("[TryChangeView] succeed")
}
+ if d.consensus.currentHeight >= d.chainParams.DPoSConfiguration.ChangeViewV1Height {
+ return
+ }
+
if d.consensus.viewOffset >= maxViewOffset {
m := &dmsg.ResetView{
Sponsor: d.GetPublicKey(),
@@ -658,14 +681,20 @@ func (d *DPOSManager) clearInactiveData(p *payload.InactiveArbitrators) {
func (d *DPOSManager) OnRevertToDPOSTxReceived(id dpeer.PID,
tx interfaces.Transaction) {
+ log.Info("### RevertToDPoS OnRevertToDPOSTxReceived start 1, id:", id.String(), "tx hash:", tx.Hash())
if !d.isCurrentArbiter() {
+ log.Info("### RevertToDPoS OnRevertToDPOSTxReceived but is not current")
return
}
+ log.Info("### RevertToDPoS OnRevertToDPOSTxReceived start 2")
+
if err := blockchain.CheckRevertToDPOSTransaction(tx); err != nil {
log.Info("[OnRevertToDPOSTxReceived] received error evidence: ", err)
return
}
+
+ log.Info("### RevertToDPoS OnRevertToDPOSTxReceived start 3")
d.dispatcher.OnRevertToDPOSTxReceived(id, tx)
}
@@ -705,6 +734,9 @@ func (d *DPOSManager) OnResponseRevertToDPOSTxReceived(
}
func (d *DPOSManager) OnResponseResetViewReceived(msg *dmsg.ResetView) {
+ if d.consensus.currentHeight >= d.chainParams.DPoSConfiguration.ChangeViewV1Height {
+ return
+ }
if !d.isCurrentArbiter() {
return
diff --git a/dpos/manager/dposnormalhandler.go b/dpos/manager/dposnormalhandler.go
index 09ec5baaf..a60796a54 100644
--- a/dpos/manager/dposnormalhandler.go
+++ b/dpos/manager/dposnormalhandler.go
@@ -87,6 +87,12 @@ func (h *DPOSNormalHandler) ProcessProposal(id peer.PID, p *payload.DPOSProposal
func (h *DPOSNormalHandler) ChangeView(firstBlockHash *common.Uint256) {
log.Info("[OnViewChanged] clean proposal")
h.proposalDispatcher.CleanProposals(true)
+ // sign proposal with same view offset to me
+ for _, v := range h.proposalDispatcher.precociousProposals {
+ if h.consensus.GetViewOffset() == v.Proposal.ViewOffset {
+ h.proposalDispatcher.ProcessProposal(v.ID, v.Proposal, false)
+ }
+ }
}
func (h *DPOSNormalHandler) TryStartNewConsensus(b *types.Block) bool {
diff --git a/dpos/manager/dposondutyhandler.go b/dpos/manager/dposondutyhandler.go
index 4377cd3e6..8b1b31150 100644
--- a/dpos/manager/dposondutyhandler.go
+++ b/dpos/manager/dposondutyhandler.go
@@ -48,16 +48,16 @@ func (h *DPOSOnDutyHandler) ProcessProposal(id peer.PID, p *payload.DPOSProposal
func (h *DPOSOnDutyHandler) ChangeView(firstBlockHash *common.Uint256) {
- if !h.tryCreateInactiveArbitratorsTx() {
- b, ok := h.cfg.Manager.GetBlockCache().TryGetValue(*firstBlockHash)
- if !ok {
- log.Info("[OnViewChanged] get block failed for proposal")
- } else {
- log.Info("[OnViewChanged] start proposal")
- h.proposalDispatcher.CleanProposals(true)
- h.proposalDispatcher.StartProposal(b)
- }
+ // if !h.tryCreateInactiveArbitratorsTx() {
+ b, ok := h.cfg.Manager.GetBlockCache().TryGetValue(*firstBlockHash)
+ if !ok {
+ log.Info("[OnViewChanged] get block failed for proposal")
+ } else {
+ log.Info("[OnViewChanged] start proposal")
+ h.proposalDispatcher.CleanProposals(true)
+ h.proposalDispatcher.StartProposal(b)
}
+ // }
}
func (h *DPOSOnDutyHandler) TryStartNewConsensus(b *types.Block) bool {
@@ -93,8 +93,8 @@ func (h *DPOSOnDutyHandler) getActiveArbitersCount() int {
func (h *DPOSOnDutyHandler) TryCreateRevertToDPOSTx(BlockHeight uint32) bool {
// connect count is not enough
// if i am not onduty return
- activeArbitersCount := float64(h.getActiveArbitersCount())
- needCount := float64(h.cfg.Arbitrators.GetArbitersCount())*float64(4)/float64(5) + 1
+ activeArbitersCount := h.getActiveArbitersCount()
+ needCount := int(float64(h.cfg.Arbitrators.GetArbitersCount())*float64(4)/float64(5)) + 1
log.Info("[TryCreateRevertToDPOSTx] current active arbiters count:", activeArbitersCount, "need:", needCount)
if len(h.cfg.Arbitrators.GetArbitrators()) == 0 ||
len(h.cfg.Arbitrators.GetNextArbitrators()) == 0 ||
diff --git a/dpos/manager/illegalbehaviormonitor.go b/dpos/manager/illegalbehaviormonitor.go
index 9778dc2db..2ce273bc3 100644
--- a/dpos/manager/illegalbehaviormonitor.go
+++ b/dpos/manager/illegalbehaviormonitor.go
@@ -76,7 +76,7 @@ func (i *IllegalBehaviorMonitor) Reset(changeView bool) {
i.cachedProposals[k] = v
}
for k, v := range i.dispatcher.precociousProposals {
- i.cachedProposals[k] = v
+ i.cachedProposals[k] = v.Proposal
}
}
}
@@ -105,8 +105,8 @@ func (i *IllegalBehaviorMonitor) IsLegalProposal(p *payload.DPOSProposal) (*payl
}
}
for _, pre := range i.dispatcher.precociousProposals {
- if i.isProposalsIllegal(p, pre) {
- return pre, false
+ if i.isProposalsIllegal(p, pre.Proposal) {
+ return pre.Proposal, false
}
}
diff --git a/dpos/manager/proposaldispatcher.go b/dpos/manager/proposaldispatcher.go
index 8b700b9bc..8c6e7b173 100644
--- a/dpos/manager/proposaldispatcher.go
+++ b/dpos/manager/proposaldispatcher.go
@@ -8,6 +8,7 @@ package manager
import (
"bytes"
"errors"
+
"github.com/elastos/Elastos.ELA/benchmark/common/utils"
"github.com/elastos/Elastos.ELA/blockchain"
@@ -42,6 +43,11 @@ type ProposalDispatcherConfig struct {
TimeSource dtime.MedianTimeSource
}
+type ProposalWithID struct {
+ Proposal *payload.DPOSProposal
+ ID peer.PID
+}
+
type ProposalDispatcher struct {
cfg ProposalDispatcherConfig
@@ -52,7 +58,7 @@ type ProposalDispatcher struct {
acceptVotes map[common.Uint256]*payload.DPOSProposalVote
rejectedVotes map[common.Uint256]*payload.DPOSProposalVote
pendingProposals map[common.Uint256]*payload.DPOSProposal
- precociousProposals map[common.Uint256]*payload.DPOSProposal
+ precociousProposals map[common.Uint256]*ProposalWithID
pendingVotes map[common.Uint256]*payload.DPOSProposalVote
proposalProcessFinished bool
@@ -109,10 +115,12 @@ func (p *ProposalDispatcher) ProcessVote(v *payload.DPOSProposalVote,
return false, false
}
- //if anotherVote, legal := p.illegalMonitor.IsLegalVote(v); !legal {
- // p.illegalMonitor.ProcessIllegalVote(v, anotherVote)
- // return
- //}
+ if p.finishedHeight > p.cfg.ChainParams.DPoSConfiguration.ChangeViewV1Height {
+ if anotherVote, legal := p.illegalMonitor.IsLegalVote(v); !legal {
+ p.illegalMonitor.ProcessIllegalVote(v, anotherVote)
+ return
+ }
+ }
if accept {
return p.countAcceptedVote(v)
@@ -218,7 +226,7 @@ func (p *ProposalDispatcher) CleanProposals(changeView bool) {
p.currentInactiveArbitratorTx = nil
p.signedTxs = map[common.Uint256]interface{}{}
p.pendingProposals = make(map[common.Uint256]*payload.DPOSProposal)
- p.precociousProposals = make(map[common.Uint256]*payload.DPOSProposal)
+ p.precociousProposals = make(map[common.Uint256]*ProposalWithID)
p.eventAnalyzer.Clear()
} else {
@@ -230,7 +238,7 @@ func (p *ProposalDispatcher) CleanProposals(changeView bool) {
}
}
for k, v := range p.precociousProposals {
- if v.ViewOffset < currentOffset {
+ if v.Proposal.ViewOffset < currentOffset {
delete(p.precociousProposals, k)
}
}
@@ -251,7 +259,7 @@ func (p *ProposalDispatcher) ResetByCurrentView() {
p.currentInactiveArbitratorTx = nil
p.signedTxs = map[common.Uint256]interface{}{}
p.pendingProposals = make(map[common.Uint256]*payload.DPOSProposal)
- p.precociousProposals = make(map[common.Uint256]*payload.DPOSProposal)
+ p.precociousProposals = make(map[common.Uint256]*ProposalWithID)
p.eventAnalyzer.Clear()
@@ -292,7 +300,7 @@ func (p *ProposalDispatcher) ProcessProposal(id peer.PID, d *payload.DPOSProposa
if d.ViewOffset != p.cfg.Consensus.GetViewOffset() {
log.Info("have different view offset")
if d.ViewOffset > p.cfg.Consensus.GetViewOffset() {
- p.precociousProposals[d.Hash()] = d
+ p.precociousProposals[d.Hash()] = &ProposalWithID{d, id}
}
return true, !self
}
@@ -304,10 +312,12 @@ func (p *ProposalDispatcher) ProcessProposal(id peer.PID, d *payload.DPOSProposa
}
}
- //if anotherProposal, ok := p.illegalMonitor.IsLegalProposal(d); !ok {
- // p.illegalMonitor.ProcessIllegalProposal(d, anotherProposal)
- // return true, true
- //}
+ if p.finishedHeight > p.cfg.ChainParams.DPoSConfiguration.ChangeViewV1Height {
+ if anotherProposal, ok := p.illegalMonitor.IsLegalProposal(d); !ok {
+ p.illegalMonitor.ProcessIllegalProposal(d, anotherProposal)
+ return true, true
+ }
+ }
if !p.cfg.Consensus.IsArbitratorOnDuty(d.Sponsor) {
currentArbiter := p.cfg.Manager.GetArbitrators().GetNextOnDutyArbitrator(p.cfg.Consensus.GetViewOffset())
@@ -318,8 +328,8 @@ func (p *ProposalDispatcher) ProcessProposal(id peer.PID, d *payload.DPOSProposa
return true, !self
}
- currentBlock, ok := p.cfg.Manager.GetBlockCache().TryGetValue(d.BlockHash)
- if !ok || !p.cfg.Consensus.IsRunning() {
+ currentBlock, err := p.GetBlockByHash(d.BlockHash)
+ if err != nil || !p.cfg.Consensus.IsRunning() {
p.pendingProposals[d.Hash()] = d
p.cfg.Manager.OnInv(id, d.BlockHash)
log.Info("received pending proposal")
@@ -345,6 +355,15 @@ func (p *ProposalDispatcher) ProcessProposal(id peer.PID, d *payload.DPOSProposa
return true, true
}
+func (p *ProposalDispatcher) GetBlockByHash(hash common.Uint256) (*types.Block, error) {
+ block, ok := p.cfg.Manager.GetBlockCache().TryGetValue(hash)
+ if ok {
+ return block, nil
+ }
+
+ return p.cfg.Manager.GetBlockByHash(hash)
+}
+
func (p *ProposalDispatcher) AppendConfirm() {
currentVoteSlot := &payload.Confirm{
Proposal: *p.processingProposal,
@@ -379,10 +398,10 @@ func (p *ProposalDispatcher) OnBlockAdded(b *types.Block) {
func (p *ProposalDispatcher) UpdatePrecociousProposals() {
for k, v := range p.precociousProposals {
if p.cfg.Consensus.IsRunning() &&
- v.ViewOffset == p.cfg.Consensus.GetViewOffset() {
+ v.Proposal.ViewOffset == p.cfg.Consensus.GetViewOffset() {
if needRecord, _ := p.ProcessProposal(
- peer.PID{}, v, true); needRecord {
- p.illegalMonitor.AddProposal(v)
+ peer.PID{}, v.Proposal, true); needRecord {
+ p.illegalMonitor.AddProposal(v.Proposal)
}
delete(p.precociousProposals, k)
}
@@ -399,19 +418,19 @@ func (p *ProposalDispatcher) FinishConsensus(height uint32, blockHash common.Uin
p.cfg.Manager.changeOnDuty()
c := log.ConsensusEvent{EndTime: p.cfg.TimeSource.AdjustedTime(), Height: height}
p.cfg.EventMonitor.OnConsensusFinished(&c)
- p.cfg.Consensus.SetReady()
+ p.cfg.Consensus.SetReady(height)
p.CleanProposals(false)
p.resetViewRequests = make(map[string]struct{}, 0)
}
}
-func (p *ProposalDispatcher) resetConsensus() {
+func (p *ProposalDispatcher) resetConsensus(height uint32) {
log.Info("[resetConsensus] start")
defer log.Info("[resetConsensus] end")
if p.cfg.Consensus.IsRunning() {
log.Info("[resetConsensus] reset view")
- p.cfg.Consensus.SetReady()
+ p.cfg.Consensus.SetReady(height)
p.CleanProposals(false)
}
}
@@ -513,6 +532,7 @@ func (p *ProposalDispatcher) OnIllegalBlocksTxReceived(i *payload.DPOSIllegalBlo
func (p *ProposalDispatcher) OnRevertToDPOSTxReceived(id peer.PID,
tx interfaces.Transaction) {
if _, ok := p.signedTxs[tx.Hash()]; ok {
+ log.Warn("### RevertToDPoS OnRevertToDPOSTxReceived already signed, hash", tx.Hash(), "id:", id.String())
return
}
@@ -522,14 +542,20 @@ func (p *ProposalDispatcher) OnRevertToDPOSTxReceived(id peer.PID,
TxHash: tx.Hash(),
Signer: p.cfg.Manager.GetPublicKey(),
}
+ log.Warn("### RevertToDPoS OnRevertToDPOSTxReceived signer:", common.BytesToHexString(response.Signer))
var err error
if response.Sign, err = p.cfg.Account.SignTx(tx); err != nil {
+ log.Warn("### RevertToDPoS OnRevertToDPOSTxReceived err:", err)
log.Warn("[OnRevertToDPOSTxReceived] sign response message"+
" error, details: ", err.Error())
}
go func() {
+ log.Info("### RevertToDPoS OnRevertToDPOSTxReceived send to peer!")
if err := p.cfg.Network.SendMessageToPeer(id, response); err != nil {
+ log.Warn("### RevertToDPoS OnRevertToDPOSTxReceived send to peer err:", err)
log.Warn("[OnRevertToDPOSTxReceived] send msg error: ", err)
+ } else {
+ log.Info("### RevertToDPoS OnRevertToDPOSTxReceived send to peer finished!")
}
}()
@@ -605,6 +631,7 @@ func (p *ProposalDispatcher) checkInactivePayloadContent(
func (p *ProposalDispatcher) OnResponseRevertToDPOSTxReceived(
txHash *common.Uint256, signer []byte, sign []byte) {
+ log.Info("### RevertToDPoS OnResponseRevertToDPOSTxReceived current signer:", common.BytesToHexString(signer))
if p.RevertToDPOSTx == nil ||
!p.RevertToDPOSTx.Hash().IsEqual(*txHash) {
return
@@ -613,15 +640,18 @@ func (p *ProposalDispatcher) OnResponseRevertToDPOSTxReceived(
data := new(bytes.Buffer)
if err := p.RevertToDPOSTx.SerializeUnsigned(
data); err != nil {
+ log.Warn("### RevertToDPoS OnResponseRevertToDPOSTxReceived 1 err:", err)
return
}
pk, err := crypto.DecodePoint(signer)
if err != nil {
+ log.Warn("### RevertToDPoS OnResponseRevertToDPOSTxReceived 2 err:", err)
return
}
if err := crypto.Verify(*pk, data.Bytes(), sign); err != nil {
+ log.Warn("### RevertToDPoS OnResponseRevertToDPOSTxReceived 3 err:", err)
return
}
@@ -631,6 +661,9 @@ func (p *ProposalDispatcher) OnResponseRevertToDPOSTxReceived(
buf.WriteByte(byte(len(sign)))
buf.Write(sign)
pro.Parameter = buf.Bytes()
+
+ log.Info("### RevertToDPoS OnResponseRevertToDPOSTxReceived current count:", len(pro.Parameter)/crypto.SignatureScriptLength)
+
p.tryEnterDPOSState(len(pro.Parameter) / crypto.SignatureScriptLength)
}
@@ -662,9 +695,9 @@ func (p *ProposalDispatcher) OnResponseResetViewReceived(msg *dmsg.ResetView) {
log.Info("[OnResponseResetViewReceived] signer:", common.BytesToHexString(signer))
if len(p.resetViewRequests) >= p.cfg.Arbitrators.GetArbitersMajorityCount() {
- log.Info("[OnResponseResetViewReceived] signer:", common.BytesToHexString(signer))
+ log.Info("[OnResponseResetViewReceived] enough signers:", len(p.resetViewRequests))
// do reset
- p.resetConsensus()
+ p.resetConsensus(p.finishedHeight)
p.resetViewRequests = make(map[string]struct{}, 0)
}
}
@@ -715,13 +748,17 @@ func (p *ProposalDispatcher) OnResponseInactiveArbitratorsReceived(
func (p *ProposalDispatcher) tryEnterDPOSState(signCount int) bool {
minSignCount := int(float64(p.cfg.Arbitrators.GetArbitersCount())*
state.MajoritySignRatioNumerator/state.MajoritySignRatioDenominator) + 1
+ log.Info("### RevertToDPoS OnResponseRevertToDPOSTxReceived current need count:", minSignCount, "current count:", signCount)
if signCount >= minSignCount {
+ log.Info("### RevertToDPoS OnResponseRevertToDPOSTxReceived enough! try to append to tx pool")
payload := p.RevertToDPOSTx.Payload().(*payload.RevertToDPOS)
p.cfg.Arbitrators.SetNeedRevertToDPOSTX(true)
err := p.cfg.Manager.AppendToTxnPool(p.RevertToDPOSTx)
if err != nil {
log.Warnf("[tryEnterDPOSState] err %s", err)
}
+
+ log.Info("### RevertToDPoS OnResponseRevertToDPOSTxReceived enough! added to tx pool")
p.cfg.Manager.clearRevertToDPOSData(payload)
return true
}
@@ -1039,7 +1076,7 @@ func NewDispatcherAndIllegalMonitor(cfg ProposalDispatcherConfig) (
acceptVotes: make(map[common.Uint256]*payload.DPOSProposalVote),
rejectedVotes: make(map[common.Uint256]*payload.DPOSProposalVote),
pendingProposals: make(map[common.Uint256]*payload.DPOSProposal),
- precociousProposals: make(map[common.Uint256]*payload.DPOSProposal),
+ precociousProposals: make(map[common.Uint256]*ProposalWithID),
pendingVotes: make(map[common.Uint256]*payload.DPOSProposalVote),
signedTxs: make(map[common.Uint256]interface{}),
firstBadNetworkRecover: true,
diff --git a/dpos/manager/view.go b/dpos/manager/view.go
index 307ccf72f..d95a1f9be 100644
--- a/dpos/manager/view.go
+++ b/dpos/manager/view.go
@@ -7,6 +7,7 @@ package manager
import (
"bytes"
+ "math"
"time"
"github.com/elastos/Elastos.ELA/common"
@@ -14,16 +15,22 @@ import (
"github.com/elastos/Elastos.ELA/dpos/state"
)
+const (
+ ChangeViewAddStep = uint32(3)
+ ChangeViewMulStep = uint32(20)
+)
+
type ViewListener interface {
OnViewChanged(isOnDuty bool)
}
type view struct {
- publicKey []byte
- signTolerance time.Duration
- viewStartTime time.Time
- isDposOnDuty bool
- arbitrators state.Arbitrators
+ publicKey []byte
+ signTolerance time.Duration
+ viewStartTime time.Time
+ isDposOnDuty bool
+ changeViewV1Height uint32
+ arbitrators state.Arbitrators
listener ViewListener
}
@@ -45,8 +52,32 @@ func (v *view) ResetView(t time.Time) {
}
func (v *view) ChangeView(viewOffset *uint32, now time.Time) {
- offset, offsetTime := v.calculateOffsetTime(v.viewStartTime, now)
- *viewOffset += uint32(offset)
+ offset, offsetTime := v.calculateOffsetTimeV0(v.viewStartTime, now)
+ *viewOffset += offset
+
+ v.viewStartTime = now.Add(-offsetTime)
+
+ if offset > 0 {
+ currentArbiter := v.arbitrators.GetNextOnDutyArbitrator(*viewOffset)
+
+ v.isDposOnDuty = bytes.Equal(currentArbiter, v.publicKey)
+ log.Info("current onduty arbiter:",
+ common.BytesToHexString(currentArbiter))
+
+ v.listener.OnViewChanged(v.isDposOnDuty)
+ }
+}
+
+func (v *view) ChangeViewV1(viewOffset *uint32, now time.Time) bool {
+ arbitersCount := v.arbitrators.GetArbitersCount()
+
+ offset, offsetTime := v.calculateOffsetTimeV1(*viewOffset, v.viewStartTime, now, uint32(arbitersCount))
+ if offset == *viewOffset {
+ return false
+ }
+ log.Info("ChangeView succeed, offset from:", *viewOffset, "to:", offset)
+
+ *viewOffset = offset
v.viewStartTime = now.Add(-offsetTime)
if offset > 0 {
@@ -58,9 +89,11 @@ func (v *view) ChangeView(viewOffset *uint32, now time.Time) {
v.listener.OnViewChanged(v.isDposOnDuty)
}
+
+ return true
}
-func (v *view) calculateOffsetTime(startTime time.Time,
+func (v *view) calculateOffsetTimeV0(startTime time.Time,
now time.Time) (uint32, time.Duration) {
duration := now.Sub(startTime)
offset := duration / v.signTolerance
@@ -69,6 +102,66 @@ func (v *view) calculateOffsetTime(startTime time.Time,
return uint32(offset), offsetTime
}
+func (v *view) calculateOffsetTimeV1(currentViewOffset uint32, startTime time.Time,
+ now time.Time, arbitersCount uint32) (uint32, time.Duration) {
+
+ currentOffset := currentViewOffset
+ duration := now.Sub(startTime)
+
+ var offsetSeconds time.Duration
+ if currentOffset < arbitersCount {
+ offsetSeconds = 5 * time.Second
+ } else {
+ // view 18: 5+ 1*3 * 20^1 = 65
+ // view 19: 5+ 2*3 * 20^1 = 125
+ // view 20: 5+ 3*3 * 20^1 = 185
+ // view 21: 5+ 4*3 * 20^1 = 245
+ // view 22: 5+ 5*3 * 20^1 = 305
+ // view 23: 5+ 6*3 * 20^1 = 365
+ // view 24: 5+ 7*3 * 20^1 = 425
+ // view 25: 5+ 8*3 * 20^1 = 485
+ // view 26: 5+ 9*3 * 20^1 = 545
+ // view 27: 5+10*3 * 20^1 = 605
+ // view 28: 5+11*3 * 20^1 = 665
+ // view 29: 5+12*3 * 20^1 = 725
+ // view 30: 5+13*3 * 20^1 = 785
+ // view 31: 5+14*3 * 20^1 = 845
+ // view 32: 5+15*3 * 20^1 = 905
+ // view 33: 5+16*3 * 20^1 = 965
+ // view 34: 5+17*3 * 20^1 = 1025
+ // view 35: 5+18*3 * 20^1 = 1085
+ offsetSeconds = time.Duration(5+(1+currentOffset-arbitersCount)*ChangeViewAddStep*
+ uint32(math.Pow(float64(ChangeViewMulStep), float64(currentOffset/arbitersCount)))) * time.Second
+ }
+ for duration >= offsetSeconds {
+ currentOffset++
+ duration -= offsetSeconds
+ if currentOffset < arbitersCount {
+ offsetSeconds = 5 * time.Second
+ } else {
+ offsetSeconds = time.Duration(5+(currentOffset-arbitersCount)*ChangeViewAddStep*
+ uint32(math.Pow(float64(ChangeViewMulStep), float64(currentOffset/arbitersCount)))) * time.Second
+ }
+ }
+
+ return currentOffset, duration
+}
+
+func (v *view) calculateOffsetTimeV2(currentViewOffset uint32, startTime time.Time,
+ now time.Time, arbitersCount uint32) (uint32, time.Duration) {
+ duration := now.Sub(startTime)
+ currentOffset := currentViewOffset
+
+ offsetSeconds := time.Duration(5+(currentOffset-arbitersCount)) * time.Second
+ for duration >= offsetSeconds {
+ currentOffset++
+ duration -= offsetSeconds
+ offsetSeconds = time.Duration(5+(currentOffset-arbitersCount)) * time.Second
+ }
+
+ return currentOffset, duration
+}
+
func (v *view) TryChangeView(viewOffset *uint32, now time.Time) bool {
if now.After(v.viewStartTime.Add(v.signTolerance)) {
log.Info("[TryChangeView] succeed")
@@ -78,6 +171,13 @@ func (v *view) TryChangeView(viewOffset *uint32, now time.Time) bool {
return false
}
+func (v *view) TryChangeViewV1(viewOffset *uint32, now time.Time) bool {
+ if now.After(v.viewStartTime.Add(v.signTolerance)) {
+ return v.ChangeViewV1(viewOffset, now)
+ }
+ return false
+}
+
func (v *view) GetViewInterval() time.Duration {
return v.signTolerance
}
diff --git a/dpos/manager/view_test.go b/dpos/manager/view_test.go
new file mode 100644
index 000000000..ea8d95e9f
--- /dev/null
+++ b/dpos/manager/view_test.go
@@ -0,0 +1,445 @@
+package manager
+
+import (
+ "fmt"
+ "math"
+ "math/rand"
+ "sort"
+ "testing"
+ "time"
+
+ "github.com/elastos/Elastos.ELA/utils/test"
+)
+
+func TestView_ChangeViewV1(t *testing.T) {
+ test.SkipShort(t)
+ print("[")
+ for step := uint32(1); step <= 50; step++ {
+ for i := 0; i < 100; i++ {
+ // Create an array of 36 uint32 values
+ arr := [36]uint32{}
+
+ // Fill the array with random values from 0 to 36
+ for j := 0; j < len(arr); j++ {
+ arr[j] = uint32(rand.Intn(10))
+ }
+ ti, _ := changeViewToSameV1(arr, step)
+ fmt.Printf("[%.2f,%d],", float64(step)/10, int(ti.Seconds()))
+ }
+ }
+ print("]")
+}
+
+func TestView_ChangeViewV2(t *testing.T) {
+ test.SkipShort(t)
+ print("[")
+ for step := uint32(2); step <= 36; step++ {
+ for i := 0; i < 100; i++ {
+ // Create an array of 36 uint32 values
+ arr := make([]offsetIndex, 36, 36)
+ // Fill the array with random values from 0 to 36
+ for i := 0; i < 36; i++ {
+ arr[i] = offsetIndex{
+ Offset: uint32(rand.Intn(36)),
+ Index: i,
+ }
+ }
+ ti, _ := changeViewToSameV2(arr, step)
+ print("[", step, ",", int(ti.Seconds()), "],")
+ }
+ }
+ print("]")
+}
+
+func TestView_ChangeViewV3(t *testing.T) {
+ test.SkipShort(t)
+ addTime := uint32(1)
+ offsetTime := 60 * time.Second
+ arbitersCount := 36
+ print("[")
+ for step := uint32(2); step <= 36; step++ {
+ currentOffset, _, _ := calculateOffsetTimeV3(addTime, step, 0, offsetTime, uint32(arbitersCount))
+
+ for i := 0; i < 100; i++ {
+ // Create an array of 36 uint32 values
+ arr := make([]offsetIndex, arbitersCount, arbitersCount)
+ // Fill the array with random values from 0 to arbitersCount
+ for i := 0; i < arbitersCount; i++ {
+ arr[i] = offsetIndex{
+ Offset: uint32(rand.Intn(int(currentOffset) + 1)),
+ Index: i,
+ }
+ }
+ ti, _ := changeViewToSameV3(arr, addTime, step)
+ print("[", step, ",", int(ti.Seconds()), "],")
+ }
+ }
+ print("]")
+}
+
+func TestView_ChangeViewV3_Special(t *testing.T) {
+ test.SkipShort(t)
+ addTime := uint32(1)
+ offsetTime := 60 * time.Second
+ arbitersCount := 36
+ print("[")
+ for step := uint32(2); step <= 36; step++ {
+ currentOffset, _, _ := calculateOffsetTimeV3(addTime, step, 0, offsetTime, uint32(arbitersCount))
+
+ // Create an array of 36 uint32 values
+ arr := make([]offsetIndex, arbitersCount, arbitersCount)
+ viewOffset1 := uint32(0)
+ viewOffset2 := currentOffset
+ for i := 0; i < arbitersCount; i++ {
+ if i < arbitersCount/2 {
+ arr[i] = offsetIndex{
+ Offset: viewOffset1,
+ Index: i,
+ }
+ } else {
+ arr[i] = offsetIndex{
+ Offset: viewOffset2,
+ Index: i,
+ }
+ }
+
+ }
+
+ ti, _ := changeViewToSameV3(arr, addTime, step)
+ print("[", step, ",", int(ti.Seconds()), "],")
+ }
+ print("]")
+}
+
+func TestView_ChangeViewV4(t *testing.T) {
+ test.SkipShort(t)
+ addTime := uint32(1)
+ offsetTime := 3600 * time.Second
+ arbitersCount := 36
+ print("[")
+ for step := uint32(2); step <= 36; step++ {
+ currentOffset, _, _ := calculateOffsetTimeV4(addTime, step, 0, offsetTime, uint32(arbitersCount))
+
+ for i := 0; i < 100; i++ {
+ // Create an array of 36 uint32 values
+ arr := make([]offsetIndex, arbitersCount, arbitersCount)
+ // Fill the array with random values from 0 to arbitersCount
+ for i := 0; i < arbitersCount; i++ {
+ arr[i] = offsetIndex{
+ Offset: uint32(rand.Intn(int(currentOffset) + 1)),
+ Index: i,
+ }
+ }
+ ti, _ := changeViewToSameV4(arr, addTime, step)
+ print("[", step, ",", int(ti.Seconds()), "],")
+ }
+ }
+ print("]")
+}
+
+func TestView_ChangeViewV4_Special(t *testing.T) {
+ test.SkipShort(t)
+ addTime := uint32(3)
+ offsetTime := 7200 * time.Second
+ arbitersCount := 36
+ print("[")
+ for step := uint32(2); step <= 36; step++ {
+ currentOffset, _, _ := calculateOffsetTimeV4(addTime, step, 0, offsetTime, uint32(arbitersCount))
+
+ // Create an array of 36 uint32 values
+ arr := make([]offsetIndex, arbitersCount, arbitersCount)
+ viewOffset1 := uint32(0)
+ viewOffset2 := currentOffset
+ for i := 0; i < arbitersCount; i++ {
+ if i < arbitersCount/2 {
+ arr[i] = offsetIndex{
+ Offset: viewOffset1,
+ Index: i,
+ }
+ } else {
+ arr[i] = offsetIndex{
+ Offset: viewOffset2,
+ Index: i,
+ }
+ }
+
+ }
+
+ ti, _ := changeViewToSameV4(arr, addTime, step)
+ print("[", step, ",", int(ti.Seconds()), "],")
+ }
+ print("]")
+}
+
+func calculateOffsetTimeV2(step float64, currentViewOffset uint32, duration time.Duration, arbitersCount uint32) (uint32, time.Duration, time.Duration) {
+ currentOffset := currentViewOffset
+
+ offsetSeconds := time.Duration(5*math.Pow(step, float64(currentOffset/arbitersCount))) * time.Second
+ for duration >= offsetSeconds {
+ currentOffset++
+ duration -= offsetSeconds
+ offsetSeconds = time.Duration(5*math.Pow(step, float64(currentOffset/arbitersCount))) * time.Second
+ }
+
+ return currentOffset, duration, offsetSeconds
+}
+
+func calculateOffsetTimeV3(addTime uint32, step uint32, currentViewOffset uint32, duration time.Duration, arbitersCount uint32) (uint32, time.Duration, time.Duration) {
+ currentOffset := currentViewOffset
+
+ var offsetSeconds time.Duration
+ if currentOffset < arbitersCount {
+ offsetSeconds = 5 * time.Second
+ } else {
+ offsetSeconds = time.Duration(5+(currentOffset-arbitersCount)*addTime*
+ uint32(math.Pow(float64(step), float64(currentOffset/arbitersCount)))) * time.Second
+ }
+ for duration >= offsetSeconds {
+ currentOffset++
+ duration -= offsetSeconds
+ if currentOffset < arbitersCount {
+ offsetSeconds = 5 * time.Second
+ } else {
+ offsetSeconds = time.Duration(5+(currentOffset-arbitersCount)*addTime*
+ uint32(math.Pow(float64(step), float64(currentOffset/arbitersCount)))) * time.Second
+ }
+ }
+
+ return currentOffset, duration, offsetSeconds
+}
+
+func calculateOffsetTimeV4(addTime uint32, step uint32, currentViewOffset uint32, duration time.Duration, arbitersCount uint32) (uint32, time.Duration, time.Duration) {
+ currentOffset := currentViewOffset
+
+ var offsetSeconds time.Duration
+ if currentOffset < arbitersCount {
+ offsetSeconds = 5 * time.Second
+ } else {
+ offsetSeconds = time.Duration(5*uint32(math.Pow(float64(step),
+ float64(currentOffset/arbitersCount)))+(currentOffset-arbitersCount)*addTime) * time.Second
+ }
+ for duration >= offsetSeconds {
+ currentOffset++
+ duration -= offsetSeconds
+ if currentOffset < arbitersCount {
+ offsetSeconds = 5 * time.Second
+ } else {
+ offsetSeconds = time.Duration(5*uint32(math.Pow(float64(step),
+ float64(currentOffset/arbitersCount)))+(currentOffset-arbitersCount)*addTime) * time.Second
+ }
+ }
+
+ return currentOffset, duration, offsetSeconds
+}
+
+type viewTime struct {
+ Times int
+ K map[int]struct{}
+}
+
+type offsetIndex struct {
+ Offset uint32
+ Index int
+}
+
+func changeViewToSameV2(viewOffsets []offsetIndex, step uint32) (sameTime time.Duration, consensusTime time.Duration) {
+
+ sort.Slice(viewOffsets, func(i, j int) bool {
+ return viewOffsets[i].Offset > viewOffsets[j].Offset
+ })
+
+ // 2/3+1 same view offset
+ smallestK := math.MaxInt32
+ for currentTime := 5 * time.Second; ; currentTime += 5 * time.Second {
+ offsets := make(map[uint32]viewTime)
+ var offsetSeconds time.Duration
+
+ for k, v := range viewOffsets {
+ var offset uint32
+ offset, _, offsetSeconds = calculateOffsetTimeV2(float64(step), v.Offset, currentTime, uint32(len(viewOffsets)))
+ if offsets[offset].Times >= 24 {
+ sameTime = currentTime
+ if smallestK > v.Index {
+ smallestK = v.Index
+ }
+
+ if smallestK != math.MaxInt32 {
+ randomIndex := rand.Intn(36)
+ consensusTime = sameTime + time.Duration(randomIndex)*offsetSeconds
+ return
+ }
+ }
+
+ if ot, ok := offsets[offset]; ok {
+ ot.K[k] = struct{}{}
+ offsets[offset] = viewTime{
+ Times: ot.Times + 1,
+ K: ot.K,
+ }
+ } else {
+ offsets[offset] = viewTime{
+ Times: 1,
+ K: make(map[int]struct{}),
+ }
+ offsets[offset].K[k] = struct{}{}
+ }
+ }
+ }
+}
+
+func calculateOffsetTimeV1(step uint32, currentViewOffset uint32, duration time.Duration, arbitersCount uint32) (uint32, time.Duration, time.Duration) {
+ currentOffset := currentViewOffset
+
+ var offsetSeconds time.Duration
+ if currentOffset < arbitersCount {
+ offsetSeconds = 5 * time.Second
+ } else {
+ offsetSeconds = time.Duration(5000+float64(currentOffset-arbitersCount)*(float64(step)*1000/10)) * time.Millisecond
+ }
+ for duration >= offsetSeconds {
+ currentOffset++
+ duration -= offsetSeconds
+ if currentOffset < arbitersCount {
+ offsetSeconds = 5 * time.Second
+ } else {
+ offsetSeconds = time.Duration(5+(currentOffset-arbitersCount)*step) * time.Second
+ }
+ }
+
+ return currentOffset, duration, offsetSeconds
+}
+
+func changeViewToSameV1(viewOffsets [36]uint32, step uint32) (sameTime time.Duration, consensusTime time.Duration) {
+
+ // 2/3+1 same view offset
+ for currentTime := 5 * time.Second; ; currentTime += 5 * time.Second {
+ offsets := make(map[uint32]viewTime)
+ var offsetSeconds time.Duration
+ for k, v := range viewOffsets {
+ var offset uint32
+ offset, _, offsetSeconds = calculateOffsetTimeV1(step, v, currentTime, 36)
+ if offsets[offset].Times >= 24 {
+ sameTime = currentTime
+
+ smallestK := math.MaxInt32
+ for i := 1; i <= len(viewOffsets); i++ {
+ if _, ok := offsets[offset].K[i]; !ok {
+ if smallestK > i {
+ smallestK = i
+ break
+ }
+ }
+ }
+ randomIndex := rand.Intn(36)
+ consensusTime = sameTime + time.Duration(randomIndex)*offsetSeconds
+
+ return
+ }
+
+ if ot, ok := offsets[offset]; ok {
+ ot.K[k] = struct{}{}
+ offsets[offset] = viewTime{
+ Times: ot.Times + 1,
+ K: ot.K,
+ }
+ } else {
+ offsets[offset] = viewTime{
+ Times: 1,
+ K: make(map[int]struct{}),
+ }
+ offsets[offset].K[k] = struct{}{}
+ }
+ }
+
+ }
+}
+
+func changeViewToSameV3(viewOffsets []offsetIndex, addTime uint32, step uint32) (sameTime time.Duration, consensusTime time.Duration) {
+
+ sort.Slice(viewOffsets, func(i, j int) bool {
+ return viewOffsets[i].Offset > viewOffsets[j].Offset
+ })
+
+ // 2/3+1 same view offset
+ smallestK := math.MaxInt32
+ for currentTime := 5 * time.Second; ; currentTime += 5 * time.Second {
+ offsets := make(map[uint32]viewTime)
+ var offsetSeconds time.Duration
+
+ for k, v := range viewOffsets {
+ var offset uint32
+ offset, _, offsetSeconds = calculateOffsetTimeV3(addTime, step, v.Offset, currentTime, uint32(len(viewOffsets)))
+ if offsets[offset].Times >= 24 {
+ sameTime = currentTime
+ if smallestK > v.Index {
+ smallestK = v.Index
+ }
+
+ if smallestK != math.MaxInt32 {
+ randomIndex := rand.Intn(36)
+ consensusTime = sameTime + time.Duration(randomIndex)*offsetSeconds
+ return
+ }
+ }
+
+ if ot, ok := offsets[offset]; ok {
+ ot.K[k] = struct{}{}
+ offsets[offset] = viewTime{
+ Times: ot.Times + 1,
+ K: ot.K,
+ }
+ } else {
+ offsets[offset] = viewTime{
+ Times: 1,
+ K: make(map[int]struct{}),
+ }
+ offsets[offset].K[k] = struct{}{}
+ }
+ }
+ }
+}
+
+func changeViewToSameV4(viewOffsets []offsetIndex, addTime uint32, step uint32) (sameTime time.Duration, consensusTime time.Duration) {
+
+ sort.Slice(viewOffsets, func(i, j int) bool {
+ return viewOffsets[i].Offset > viewOffsets[j].Offset
+ })
+
+ // 2/3+1 same view offset
+ smallestK := math.MaxInt32
+ for currentTime := 5 * time.Second; ; currentTime += 5 * time.Second {
+ offsets := make(map[uint32]viewTime)
+ var offsetSeconds time.Duration
+
+ for k, v := range viewOffsets {
+ var offset uint32
+ offset, _, offsetSeconds = calculateOffsetTimeV4(addTime, step, v.Offset, currentTime, uint32(len(viewOffsets)))
+ if offsets[offset].Times >= 24 {
+ sameTime = currentTime
+ if smallestK > v.Index {
+ smallestK = v.Index
+ }
+
+ if smallestK != math.MaxInt32 {
+ randomIndex := rand.Intn(36)
+ consensusTime = sameTime + time.Duration(randomIndex)*offsetSeconds
+ return
+ }
+ }
+
+ if ot, ok := offsets[offset]; ok {
+ ot.K[k] = struct{}{}
+ offsets[offset] = viewTime{
+ Times: ot.Times + 1,
+ K: ot.K,
+ }
+ } else {
+ offsets[offset] = viewTime{
+ Times: 1,
+ K: make(map[int]struct{}),
+ }
+ offsets[offset].K[k] = struct{}{}
+ }
+ }
+ }
+}
diff --git a/dpos/state/arbitrators.go b/dpos/state/arbitrators.go
index 5f1334a05..4d2575b02 100644
--- a/dpos/state/arbitrators.go
+++ b/dpos/state/arbitrators.go
@@ -29,6 +29,7 @@ import (
"github.com/elastos/Elastos.ELA/core/types/interfaces"
"github.com/elastos/Elastos.ELA/core/types/payload"
"github.com/elastos/Elastos.ELA/cr/state"
+ "github.com/elastos/Elastos.ELA/crypto"
"github.com/elastos/Elastos.ELA/dpos/p2p/peer"
"github.com/elastos/Elastos.ELA/events"
"github.com/elastos/Elastos.ELA/utils"
@@ -128,6 +129,15 @@ func (a *Arbiters) SetNeedRevertToDPOSTX(need bool) {
a.NeedRevertToDPOSTX = need
}
+func GetOwnerKeyStandardProgramHash(ownerKey []byte) (ownKeyProgramHash *common.Uint168, err error) {
+ if len(ownerKey) == crypto.NegativeBigLength {
+ ownKeyProgramHash, err = contract.PublicKeyToStandardProgramHash(ownerKey)
+ } else {
+ ownKeyProgramHash = common.ToProgramHash(byte(contract.PrefixStandard), ownerKey)
+ }
+ return ownKeyProgramHash, err
+}
+
func (a *Arbiters) SetNeedNextTurnDPOSInfo(need bool) {
a.mtx.Lock()
defer a.mtx.Unlock()
@@ -525,6 +535,13 @@ func (a *Arbiters) normalChange(height uint32) error {
}
func (a *Arbiters) notifyNextTurnDPOSInfoTx(blockHeight, versionHeight uint32, forceChange bool) {
+ if blockHeight > a.ChainParams.DPoSConfiguration.DexStartHeight {
+ nextTurnDPOSInfoTx := a.createNextTurnDPOSInfoTransactionV2(blockHeight, forceChange)
+ go events.Notify(events.ETAppendTxToTxPool, nextTurnDPOSInfoTx)
+
+ return
+ }
+
if blockHeight+uint32(a.ChainParams.DPoSConfiguration.NormalArbitratorsCount+len(a.ChainParams.DPoSConfiguration.CRCArbiters)) >= a.DPoSV2ActiveHeight {
nextTurnDPOSInfoTx := a.createNextTurnDPOSInfoTransactionV1(blockHeight, forceChange)
go events.Notify(events.ETAppendTxToTxPool, nextTurnDPOSInfoTx)
@@ -534,6 +551,7 @@ func (a *Arbiters) notifyNextTurnDPOSInfoTx(blockHeight, versionHeight uint32, f
nextTurnDPOSInfoTx := a.createNextTurnDPOSInfoTransactionV0(blockHeight, forceChange)
go events.Notify(events.ETAppendTxToTxPool, nextTurnDPOSInfoTx)
+
return
}
@@ -718,7 +736,7 @@ func (a *Arbiters) getDPoSV2RewardsV2(dposReward common.Fixed64, sponsor []byte,
var isCR bool
for _, cr := range a.CurrentCRCArbitersMap {
if bytes.Equal(sponsor, cr.GetNodePublicKey()) {
- ownerProgramHash, _ := contract.PublicKeyToStandardProgramHash(cr.GetOwnerPublicKey())
+ ownerProgramHash, _ := GetOwnerKeyStandardProgramHash(cr.GetOwnerPublicKey())
stakeProgramHash := common.Uint168FromCodeHash(
byte(contract.PrefixDPoSV2), ownerProgramHash.ToCodeHash())
ownerAddr, _ := stakeProgramHash.ToAddress()
@@ -737,7 +755,7 @@ func (a *Arbiters) getDPoSV2RewardsV2(dposReward common.Fixed64, sponsor []byte,
log.Error("v2 accumulateReward Sponsor not exist ", hex.EncodeToString(sponsor))
return
}
- ownerProgramHash, _ := contract.PublicKeyToStandardProgramHash(producer.OwnerPublicKey())
+ ownerProgramHash, _ := GetOwnerKeyStandardProgramHash(producer.OwnerPublicKey())
stakeProgramHash := common.Uint168FromCodeHash(
byte(contract.PrefixDPoSV2), ownerProgramHash.ToCodeHash())
ownerAddr, _ := stakeProgramHash.ToAddress()
@@ -998,7 +1016,7 @@ func (a *Arbiters) distributeWithNormalArbitratorsV3(height uint32, reward commo
if err != nil {
panic("get owner public key err:" + err.Error())
}
- programHash, err := contract.PublicKeyToStandardProgramHash(opk)
+ programHash, err := GetOwnerKeyStandardProgramHash(opk)
if err != nil {
panic("public key to standard program hash err:" + err.Error())
}
@@ -1011,7 +1029,7 @@ func (a *Arbiters) distributeWithNormalArbitratorsV3(height uint32, reward commo
individualCRCProducerReward.String(), individualBlockConfirmReward.String(), votes.String())
} else {
pk := arbiter.GetOwnerPublicKey()
- programHash, err := contract.PublicKeyToStandardProgramHash(pk)
+ programHash, err := GetOwnerKeyStandardProgramHash(pk)
if err != nil {
rewardHash = *a.ChainParams.DestroyELAProgramHash
} else {
@@ -1084,7 +1102,7 @@ func (a *Arbiters) distributeWithNormalArbitratorsV2(height uint32, reward commo
rewardHash = *a.ChainParams.DestroyELAProgramHash
} else {
pk := arbiter.GetOwnerPublicKey()
- programHash, err := contract.PublicKeyToStandardProgramHash(pk)
+ programHash, err := GetOwnerKeyStandardProgramHash(pk)
if err != nil {
rewardHash = *a.ChainParams.DestroyELAProgramHash
} else {
@@ -1145,7 +1163,7 @@ func (a *Arbiters) distributeWithNormalArbitratorsV1(height uint32, reward commo
rewardHash = *a.ChainParams.DestroyELAProgramHash
} else {
pk := arbiter.GetOwnerPublicKey()
- programHash, err := contract.PublicKeyToStandardProgramHash(pk)
+ programHash, err := GetOwnerKeyStandardProgramHash(pk)
if err != nil {
rewardHash = *a.ChainParams.DestroyELAProgramHash
} else {
@@ -1860,7 +1878,6 @@ func (a *Arbiters) getChangeType(height uint32) (ChangeType, uint32) {
func (a *Arbiters) cleanArbitrators(height uint32) {
oriCurrentCRCArbitersMap := copyCRCArbitersMap(a.CurrentCRCArbitersMap)
- oriLastArbitrators := a.LastArbitrators
oriCurrentArbitrators := a.CurrentArbitrators
oriCurrentCandidates := a.CurrentCandidates
oriNextCRCArbitersMap := copyCRCArbitersMap(a.nextCRCArbitersMap)
@@ -1869,7 +1886,6 @@ func (a *Arbiters) cleanArbitrators(height uint32) {
oriDutyIndex := a.DutyIndex
a.History.Append(height, func() {
a.CurrentCRCArbitersMap = make(map[common.Uint168]ArbiterMember)
- a.LastArbitrators = make([]ArbiterMember, 0)
a.CurrentArbitrators = make([]ArbiterMember, 0)
a.CurrentCandidates = make([]ArbiterMember, 0)
a.nextCRCArbitersMap = make(map[common.Uint168]ArbiterMember)
@@ -1878,7 +1894,6 @@ func (a *Arbiters) cleanArbitrators(height uint32) {
a.DutyIndex = 0
}, func() {
a.CurrentCRCArbitersMap = oriCurrentCRCArbitersMap
- a.LastArbitrators = oriLastArbitrators
a.CurrentArbitrators = oriCurrentArbitrators
a.CurrentCandidates = oriCurrentCandidates
a.nextCRCArbitersMap = oriNextCRCArbitersMap
@@ -1978,6 +1993,56 @@ func (a *Arbiters) createNextTurnDPOSInfoTransactionV0(blockHeight uint32, force
)
}
+func (a *Arbiters) createNextTurnDPOSInfoTransactionV2(blockHeight uint32, forceChange bool) interfaces.Transaction {
+
+ var nextTurnDPOSInfo payload.NextTurnDPOSInfo
+ nextTurnDPOSInfo.CRPublicKeys = make([][]byte, 0)
+ nextTurnDPOSInfo.DPOSPublicKeys = make([][]byte, 0)
+ var workingHeight uint32
+ if forceChange {
+ workingHeight = blockHeight
+ } else {
+ workingHeight = blockHeight + uint32(a.ChainParams.DPoSConfiguration.NormalArbitratorsCount+len(a.ChainParams.DPoSConfiguration.CRCArbiters))
+ }
+ nextTurnDPOSInfo.WorkingHeight = workingHeight
+ for _, v := range a.nextCRCArbiters {
+ nodePK := v.GetNodePublicKey()
+ if v.IsNormal() {
+ nextTurnDPOSInfo.CRPublicKeys = append(nextTurnDPOSInfo.CRPublicKeys, nodePK)
+ } else {
+ nextTurnDPOSInfo.CRPublicKeys = append(nextTurnDPOSInfo.CRPublicKeys, []byte{})
+ }
+
+ nextTurnDPOSInfo.CompleteCRPublicKeys = append(nextTurnDPOSInfo.CompleteCRPublicKeys, nodePK)
+ }
+ for _, v := range a.nextArbitrators {
+ if a.isNextCRCArbitrator(v.GetNodePublicKey()) {
+ if abt, ok := v.(*crcArbiter); ok && abt.crMember.MemberState != state.MemberElected {
+ nextTurnDPOSInfo.DPOSPublicKeys = append(nextTurnDPOSInfo.DPOSPublicKeys, []byte{})
+ } else {
+ nextTurnDPOSInfo.DPOSPublicKeys = append(nextTurnDPOSInfo.DPOSPublicKeys, v.GetNodePublicKey())
+ }
+ } else {
+ nextTurnDPOSInfo.DPOSPublicKeys = append(nextTurnDPOSInfo.DPOSPublicKeys, v.GetNodePublicKey())
+ }
+ }
+
+ log.Debugf("[createNextTurnDPOSInfoTransaction] CRPublicKeys %v, DPOSPublicKeys%v\n",
+ a.ConvertToArbitersStr(nextTurnDPOSInfo.CRPublicKeys), a.ConvertToArbitersStr(nextTurnDPOSInfo.DPOSPublicKeys))
+
+ return functions.CreateTransaction(
+ common2.TxVersion09,
+ common2.NextTurnDPOSInfo,
+ payload.NextTurnDPOSInfoVersion2,
+ &nextTurnDPOSInfo,
+ []*common2.Attribute{},
+ []*common2.Input{},
+ []*common2.Output{},
+ 0,
+ []*program.Program{},
+ )
+}
+
func (a *Arbiters) createNextTurnDPOSInfoTransactionV1(blockHeight uint32, forceChange bool) interfaces.Transaction {
var nextTurnDPOSInfo payload.NextTurnDPOSInfo
@@ -2094,7 +2159,7 @@ func (a *Arbiters) getSortedProducersWithRandom(height uint32, unclaimedCount in
if a.LastRandomCandidateHeight != 0 &&
height-a.LastRandomCandidateHeight < a.ChainParams.DPoSConfiguration.RandomCandidatePeriod {
for i, p := range votedProducers {
- if common.BytesToHexString(p.info.OwnerPublicKey) == a.LastRandomCandidateOwner {
+ if common.BytesToHexString(p.info.OwnerKey) == a.LastRandomCandidateOwner {
if i < unclaimedCount+a.ChainParams.DPoSConfiguration.NormalArbitratorsCount-1 || p.state != Active {
// need get again at random.
break
@@ -2125,7 +2190,7 @@ func (a *Arbiters) getSortedProducersWithRandom(height uint32, unclaimedCount in
// todo need to use History?
a.LastRandomCandidateHeight = height
- a.LastRandomCandidateOwner = common.BytesToHexString(candidateProducer.info.OwnerPublicKey)
+ a.LastRandomCandidateOwner = common.BytesToHexString(candidateProducer.info.OwnerKey)
newProducers := make([]*Producer, 0, len(votedProducers))
newProducers = append(newProducers, votedProducers[:unclaimedCount+normalCount]...)
@@ -2164,7 +2229,7 @@ func (a *Arbiters) getRandomDposV2Producers(height uint32, unclaimedCount int, c
return strings.Compare(producerKeys[i], producerKeys[j]) < 0
})
for _, vp := range votedProducers[unclaimedCount:] {
- producerKeys = append(producerKeys, hex.EncodeToString(vp.info.OwnerPublicKey))
+ producerKeys = append(producerKeys, hex.EncodeToString(vp.info.OwnerKey))
}
sortedProducer := make([]string, 0, len(producerKeys))
count := a.ChainParams.DPoSConfiguration.NormalArbitratorsCount + len(a.ChainParams.DPoSConfiguration.CRCArbiters)
@@ -2295,7 +2360,7 @@ func (a *Arbiters) UpdateNextArbitrators(versionHeight, height uint32) error {
var newSelected bool
for _, p := range votedProducers {
producer := p
- ownerPK := common.BytesToHexString(producer.info.OwnerPublicKey)
+ ownerPK := common.BytesToHexString(producer.info.OwnerKey)
if ownerPK == a.LastRandomCandidateOwner &&
height-a.LastRandomCandidateHeight == uint32(count) {
newSelected = true
@@ -2311,7 +2376,7 @@ func (a *Arbiters) UpdateNextArbitrators(versionHeight, height uint32) error {
producer.selected = true
})
}
- ownerPK := common.BytesToHexString(producer.info.OwnerPublicKey)
+ ownerPK := common.BytesToHexString(producer.info.OwnerKey)
oriRandomInactiveCount := producer.randomCandidateInactiveCount
if ownerPK == a.LastRandomCandidateOwner {
a.History.Append(height, func() {
@@ -2443,8 +2508,8 @@ func (a *Arbiters) resetNextArbiterByCRC(versionHeight uint32, height uint32) (i
}
producer := &Producer{ // here need crc NODE public key
info: payload.ProducerInfo{
- OwnerPublicKey: pubKey,
- NodePublicKey: pubKey,
+ OwnerKey: pubKey,
+ NodePublicKey: pubKey,
},
activateRequestHeight: math.MaxUint32,
}
@@ -2682,7 +2747,7 @@ func (a *Arbiters) GetDposV2CandidatesDesc(startIndex int,
for i := startIndex; i < len(producers) && i < startIndex+a.
ChainParams.DPoSConfiguration.CandidatesCount; i++ {
ownkey, _ := hex.DecodeString(producers[i])
- hash, _ := contract.PublicKeyToStandardProgramHash(ownkey)
+ hash, _ := GetOwnerKeyStandardProgramHash(ownkey)
crc, exist := choosingArbiters[*hash]
if exist {
result = append(result, crc)
@@ -2728,8 +2793,7 @@ func (a *Arbiters) snapshotVotesStates(height uint32) error {
if producer == nil {
return errors.New("get producer by node public key failed")
}
- programHash, err := contract.PublicKeyToStandardProgramHash(
- producer.OwnerPublicKey())
+ programHash, err := GetOwnerKeyStandardProgramHash(producer.OwnerPublicKey())
if err != nil {
return err
}
@@ -2768,7 +2832,7 @@ func (a *Arbiters) snapshotVotesStates(height uint32) error {
if producer == nil {
return errors.New("get producer by node public key failed")
}
- programHash, err := contract.PublicKeyToStandardProgramHash(producer.OwnerPublicKey())
+ programHash, err := GetOwnerKeyStandardProgramHash(producer.OwnerPublicKey())
if err != nil {
return err
}
@@ -2997,8 +3061,8 @@ func (a *Arbiters) initArbitrators(chainParams *config.Configuration) error {
}
producer := &Producer{ // here need crc NODE public key
info: payload.ProducerInfo{
- OwnerPublicKey: pubKey,
- NodePublicKey: pubKey,
+ OwnerKey: pubKey,
+ NodePublicKey: pubKey,
},
activateRequestHeight: math.MaxUint32,
}
diff --git a/dpos/state/checkpoint.go b/dpos/state/checkpoint.go
index 6a520c310..ecb40c52a 100644
--- a/dpos/state/checkpoint.go
+++ b/dpos/state/checkpoint.go
@@ -29,7 +29,7 @@ const (
// checkpointEffectiveHeight defines the minimal height Arbiters obj
// should scan to recover effective state.
- checkpointEffectiveHeight = uint32(7)
+ checkpointEffectiveHeight = uint32(720)
)
// CheckPoint defines all variables need record in database
@@ -61,6 +61,11 @@ type CheckPoint struct {
arbitrators *Arbiters
}
+func (c *CheckPoint) SaveStartHeight() uint32 {
+ // same to CR
+ return c.arbitrators.ChainParams.CRConfiguration.CRVotingStartHeight
+}
+
func (c *CheckPoint) StartHeight() uint32 {
return uint32(math.Min(float64(c.arbitrators.ChainParams.VoteStartHeight),
float64(c.arbitrators.ChainParams.CRCOnlyDPOSHeight-
diff --git a/dpos/state/crcarbiter.go b/dpos/state/crcarbiter.go
index cd61d2684..0c0c62e8e 100644
--- a/dpos/state/crcarbiter.go
+++ b/dpos/state/crcarbiter.go
@@ -10,7 +10,6 @@ import (
"io"
"github.com/elastos/Elastos.ELA/common"
- "github.com/elastos/Elastos.ELA/core/contract"
"github.com/elastos/Elastos.ELA/cr/state"
"github.com/elastos/Elastos.ELA/crypto"
)
@@ -95,7 +94,7 @@ func NewCRCArbiter(nodePK []byte, ownerPK []byte, cr *state.CRMember,
crMember: cr,
nodePk: nodePK,
}
- hash, err := contract.PublicKeyToStandardProgramHash(ownerPK)
+ hash, err := GetOwnerKeyStandardProgramHash(ownerPK)
if err != nil {
return nil, err
}
diff --git a/dpos/state/dposarbiter.go b/dpos/state/dposarbiter.go
index c066e95bd..83bad1783 100644
--- a/dpos/state/dposarbiter.go
+++ b/dpos/state/dposarbiter.go
@@ -10,7 +10,6 @@ import (
"io"
"github.com/elastos/Elastos.ELA/common"
- "github.com/elastos/Elastos.ELA/core/contract"
)
type dposArbiter struct {
@@ -67,8 +66,7 @@ func NewDPoSArbiter(producer *Producer) (ArbiterMember, error) {
ar := &dposArbiter{
producer: *producer,
}
- hash, err := contract.PublicKeyToStandardProgramHash(
- producer.OwnerPublicKey())
+ hash, err := GetOwnerKeyStandardProgramHash(producer.OwnerPublicKey())
if err != nil {
return nil, err
}
diff --git a/dpos/state/dposarbiter_test.go b/dpos/state/dposarbiter_test.go
index 7e871e2d5..c1743247f 100644
--- a/dpos/state/dposarbiter_test.go
+++ b/dpos/state/dposarbiter_test.go
@@ -225,7 +225,7 @@ func producerInfoEqual(first *payload.ProducerInfo,
return false
}
- return bytes.Equal(first.OwnerPublicKey, second.OwnerPublicKey) &&
+ return bytes.Equal(first.OwnerKey, second.OwnerKey) &&
bytes.Equal(first.NodePublicKey, second.NodePublicKey) &&
bytes.Equal(first.Signature, second.Signature)
}
@@ -287,13 +287,13 @@ func randomProgramHash() *common.Uint168 {
func randomProducer() *Producer {
p := &Producer{}
p.SetInfo(payload.ProducerInfo{
- OwnerPublicKey: randomFakePK(),
- NodePublicKey: randomFakePK(),
- NickName: randomString(),
- Url: randomString(),
- Location: rand.Uint64(),
- NetAddress: randomString(),
- Signature: randomBytes(64),
+ OwnerKey: randomFakePK(),
+ NodePublicKey: randomFakePK(),
+ NickName: randomString(),
+ Url: randomString(),
+ Location: rand.Uint64(),
+ NetAddress: randomString(),
+ Signature: randomBytes(64),
})
p.SetState(ProducerState(rand.Uint32()))
p.SetRegisterHeight(rand.Uint32())
diff --git a/dpos/state/heightversion.go b/dpos/state/heightversion.go
index 230299125..08590b9ab 100644
--- a/dpos/state/heightversion.go
+++ b/dpos/state/heightversion.go
@@ -11,7 +11,6 @@ import (
"math"
"github.com/elastos/Elastos.ELA/common"
- "github.com/elastos/Elastos.ELA/core/contract"
)
// 0 - H1
@@ -58,7 +57,7 @@ func (a *Arbiters) getDposV2NormalArbitratorsDescV2(arbitratorsCount int,
result := make([]ArbiterMember, 0)
for i := 0; i < arbitratorsCount && i < len(producers); i++ {
ownkey, _ := hex.DecodeString(producers[i])
- hash, _ := contract.PublicKeyToStandardProgramHash(ownkey)
+ hash, _ := GetOwnerKeyStandardProgramHash(ownkey)
crc, exist := choosingArbiters[*hash]
if exist {
result = append(result, crc)
diff --git a/dpos/state/keyframe.go b/dpos/state/keyframe.go
index 8af96747a..27b836bcb 100644
--- a/dpos/state/keyframe.go
+++ b/dpos/state/keyframe.go
@@ -34,16 +34,16 @@ func (consesus ConsesusAlgorithm) String() string {
// StateKeyFrame holds necessary state about State
type StateKeyFrame struct {
- NodeOwnerKeys map[string]string // NodePublicKey as key, OwnerPublicKey as value
- CurrentCRNodeOwnerKeys map[string]string // NodePublicKey as key, OwnerPublicKey as value
- NextCRNodeOwnerKeys map[string]string // NodePublicKey as key, OwnerPublicKey as value
- PendingProducers map[string]*Producer
- ActivityProducers map[string]*Producer
- InactiveProducers map[string]*Producer
- CanceledProducers map[string]*Producer
- IllegalProducers map[string]*Producer
- PendingCanceledProducers map[string]*Producer
- DposV2EffectedProducers map[string]*Producer
+ NodeOwnerKeys map[string]string // (NodePublicKey as key, OwnerKey or OwnMulitCode as value)
+ CurrentCRNodeOwnerKeys map[string]string // (NodePublicKey as key, OwnerKey or OwnMulitCode as value)
+ NextCRNodeOwnerKeys map[string]string // (NodePublicKey as key, OwnerKey or OwnMulitCode value)
+ PendingProducers map[string]*Producer //OwnerKey or OwnMulitCode as key Producer pointer as value
+ ActivityProducers map[string]*Producer //OwnerKey or OwnMulitCode as key Producer pointer as value
+ InactiveProducers map[string]*Producer //OwnerKey or OwnMulitCode as key Producer pointer as value
+ CanceledProducers map[string]*Producer //OwnerKey or OwnMulitCode as key Producer pointer as value
+ IllegalProducers map[string]*Producer //OwnerKey or OwnMulitCode as key Producer pointer as value
+ PendingCanceledProducers map[string]*Producer //OwnerKey or OwnMulitCode as key Producer pointer as value
+ DposV2EffectedProducers map[string]*Producer //OwnerKey or OwnMulitCode as key Producer pointer as value
Votes map[string]struct{}
// NFT
diff --git a/dpos/state/originarbiter.go b/dpos/state/originarbiter.go
index 1622f50b6..3169ac322 100644
--- a/dpos/state/originarbiter.go
+++ b/dpos/state/originarbiter.go
@@ -9,7 +9,6 @@ import (
"io"
"github.com/elastos/Elastos.ELA/common"
- "github.com/elastos/Elastos.ELA/core/contract"
"github.com/elastos/Elastos.ELA/crypto"
)
@@ -61,7 +60,7 @@ func (o *originArbiter) Clone() ArbiterMember {
}
func NewOriginArbiter(key []byte) (ArbiterMember, error) {
- hash, err := contract.PublicKeyToStandardProgramHash(key)
+ hash, err := GetOwnerKeyStandardProgramHash(key)
if err != nil {
return nil, err
}
diff --git a/dpos/state/state.go b/dpos/state/state.go
index 0b104babb..c577778f5 100644
--- a/dpos/state/state.go
+++ b/dpos/state/state.go
@@ -24,6 +24,7 @@ import (
"github.com/elastos/Elastos.ELA/core/types/outputpayload"
"github.com/elastos/Elastos.ELA/core/types/payload"
"github.com/elastos/Elastos.ELA/cr/state"
+ "github.com/elastos/Elastos.ELA/crypto"
msg2 "github.com/elastos/Elastos.ELA/dpos/p2p/msg"
elaerr "github.com/elastos/Elastos.ELA/errors"
"github.com/elastos/Elastos.ELA/events"
@@ -176,7 +177,7 @@ func (p *Producer) NodePublicKey() []byte {
}
func (p *Producer) OwnerPublicKey() []byte {
- return p.info.OwnerPublicKey
+ return p.info.OwnerKey
}
func (p *Producer) Penalty() common.Fixed64 {
@@ -702,7 +703,7 @@ func (s *State) getProducerByOwnerPublicKey(key string) *Producer {
// updateProducerInfo updates the producer's info with value compare, any change
// will be updated.
func (s *State) updateProducerInfo(origin *payload.ProducerInfo, update *payload.ProducerInfo) {
- producer := s.getProducer(origin.OwnerPublicKey)
+ producer := s.getProducer(origin.OwnerKey)
// compare and update node nickname.
if origin.NickName != update.NickName {
@@ -716,7 +717,7 @@ func (s *State) updateProducerInfo(origin *payload.ProducerInfo, update *payload
oldKey := hex.EncodeToString(origin.NodePublicKey)
newKey := hex.EncodeToString(update.NodePublicKey)
delete(s.NodeOwnerKeys, oldKey)
- s.NodeOwnerKeys[newKey] = hex.EncodeToString(origin.OwnerPublicKey)
+ s.NodeOwnerKeys[newKey] = hex.EncodeToString(origin.OwnerKey)
}
producer.info = *update
@@ -1302,6 +1303,14 @@ func (s *State) ProcessBlock(block *types.Block, sponsor []byte, dutyIndex int)
}
}
+ // todo remove me
+ if block.Height > s.ChainParams.DPoSV2StartHeight {
+ msg2.SetPayloadVersion(msg2.DPoSV2Version)
+ }
+
+ // Commit changes here if no errors found.
+ s.History.Commit(block.Height)
+
if block.Height >= s.ChainParams.DPoSV2StartHeight &&
len(s.WithdrawableTxInfo) != 0 {
s.createDposV2ClaimRewardRealWithdrawTransaction(block.Height)
@@ -1311,14 +1320,6 @@ func (s *State) ProcessBlock(block *types.Block, sponsor []byte, dutyIndex int)
len(s.VotesWithdrawableTxInfo) != 0 {
s.createRealWithdrawTransaction(block.Height)
}
-
- // todo remove me
- if block.Height > s.ChainParams.DPoSV2StartHeight {
- msg2.SetPayloadVersion(msg2.DPoSV2Version)
- }
-
- // Commit changes here if no errors found.
- s.History.Commit(block.Height)
}
func (s *State) createRealWithdrawTransaction(height uint32) {
@@ -1698,7 +1699,7 @@ func (s *State) processTransactions(txs []interfaces.Transaction, height uint32)
for _, p := range ps {
cp := p
if cp.info.StakeUntil < height {
- key := hex.EncodeToString(cp.info.OwnerPublicKey)
+ key := hex.EncodeToString(cp.info.OwnerKey)
if cp.state != Returned && cp.state != Canceled &&
(cp.identity == DPoSV2 || (cp.identity == DPoSV1V2 && height > s.DPoSV2ActiveHeight)) {
cancelDposV2AndDposV1V2Producer(key, cp)
@@ -1833,16 +1834,34 @@ func (s *State) processTransaction(tx interfaces.Transaction, height uint32) {
s.processCancelVotes(tx, height)
}
+func GetOwnerKeyCodeHash(ownerKey []byte) (ownKeyProgramHash *common.Uint160, err error) {
+ if len(ownerKey) == crypto.NegativeBigLength {
+ ownKeyProgramHash, err = contract.PublicKeyToStandardCodeHash(ownerKey)
+ } else {
+ return common.ToCodeHash(ownerKey), nil
+ }
+ return ownKeyProgramHash, err
+}
+
+func GetOwnerKeyDepositProgramHash(ownerKey []byte) (ownKeyProgramHash *common.Uint168, err error) {
+ if len(ownerKey) == crypto.NegativeBigLength {
+ ownKeyProgramHash, err = contract.PublicKeyToDepositProgramHash(ownerKey)
+ } else {
+ ownKeyProgramHash = common.ToProgramHash(byte(contract.PrefixDeposit), ownerKey)
+ }
+ return ownKeyProgramHash, err
+}
+
// registerProducer handles the register producer transaction.
func (s *State) registerProducer(tx interfaces.Transaction, height uint32) {
info := tx.Payload().(*payload.ProducerInfo)
nickname := info.NickName
nodeKey := hex.EncodeToString(info.NodePublicKey)
- ownerKey := hex.EncodeToString(info.OwnerPublicKey)
+ ownerKey := hex.EncodeToString(info.OwnerKey)
// ignore error here because this converting process has been ensured in
// the context check already
- programHash, _ := contract.PublicKeyToDepositProgramHash(info.
- OwnerPublicKey)
+ programHash, _ := GetOwnerKeyDepositProgramHash(info.
+ OwnerKey)
amount := common.Fixed64(0)
depositOutputs := make(map[string]common.Fixed64)
@@ -1902,7 +1921,7 @@ func (s *State) registerProducer(tx interfaces.Transaction, height uint32) {
// updateProducer handles the update producer transaction.
func (s *State) updateProducer(info *payload.ProducerInfo, height uint32) {
- producer := s.getProducer(info.OwnerPublicKey)
+ producer := s.getProducer(info.OwnerKey)
originProducerIdentity := producer.identity
producerInfo := producer.info
s.History.Append(height, func() {
@@ -1928,8 +1947,8 @@ func (s *State) updateProducer(info *payload.ProducerInfo, height uint32) {
// cancelProducer handles the cancel producer transaction.
func (s *State) cancelProducer(payload *payload.ProcessProducer, height uint32) {
- key := hex.EncodeToString(payload.OwnerPublicKey)
- producer := s.getProducer(payload.OwnerPublicKey)
+ key := hex.EncodeToString(payload.OwnerKey)
+ producer := s.getProducer(payload.OwnerKey)
oriState := producer.state
s.History.Append(height, func() {
producer.state = Canceled
@@ -2402,13 +2421,16 @@ func (s *State) returnDeposit(tx interfaces.Transaction, height uint32) {
for _, input := range tx.Inputs() {
inputValue += s.DepositOutputs[input.ReferKey()]
}
-
for _, program := range tx.Programs() {
- pk := program.Code[1 : len(program.Code)-1]
- if producer := s.getProducer(pk); producer != nil {
-
+ ownerKey := make([]byte, len(program.Code), len(program.Code))
+ if contract.IsMultiSig(program.Code) {
+ copy(ownerKey, program.Code)
+ } else {
+ ownerKey = program.Code[1 : len(program.Code)-1]
+ }
+ if producer := s.getProducer(ownerKey); producer != nil {
// check deposit coin
- hash, err := contract.PublicKeyToDepositProgramHash(producer.info.OwnerPublicKey)
+ hash, err := GetOwnerKeyDepositProgramHash(producer.info.OwnerKey)
if err != nil {
log.Error("owner public key to deposit program hash: failed")
return
diff --git a/go.mod b/go.mod
index 6a17ab062..c079334fc 100644
--- a/go.mod
+++ b/go.mod
@@ -1,23 +1,58 @@
module github.com/elastos/Elastos.ELA
-go 1.16
+go 1.20
require (
github.com/RainFallsSilent/screw v1.1.1
- github.com/btcsuite/btcd v0.22.0-beta
+ github.com/btcsuite/btcd v0.23.2
github.com/go-echarts/statsview v0.3.4
github.com/gorilla/websocket v1.4.2
github.com/howeyc/gopass v0.0.0-20190910152052-7cb4b85ec19c
github.com/itchyny/base58-go v0.1.0
- github.com/mattn/go-runewidth v0.0.13 // indirect
github.com/rs/cors v1.8.0
github.com/spf13/viper v1.12.0
github.com/stretchr/testify v1.7.1
- github.com/syndtr/goleveldb v1.0.0
+ github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7
github.com/tidwall/gjson v1.9.3
github.com/urfave/cli v1.22.5
github.com/yuin/gopher-lua v0.0.0-20210529063254-f4c35e4016d9
- golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4
+ golang.org/x/crypto v0.17.0
gopkg.in/cheggaaa/pb.v1 v1.0.28
+)
+
+require (
+ github.com/antlabs/strsim v0.0.2 // indirect
+ github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 // indirect
+ github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d // indirect
+ github.com/davecgh/go-spew v1.1.1 // indirect
+ github.com/fsnotify/fsnotify v1.5.4 // indirect
+ github.com/go-echarts/go-echarts/v2 v2.2.3 // indirect
+ github.com/go-playground/locales v0.14.0 // indirect
+ github.com/go-playground/universal-translator v0.18.0 // indirect
+ github.com/go-playground/validator/v10 v10.10.1 // indirect
+ github.com/golang/snappy v0.0.4 // indirect
+ github.com/hashicorp/hcl v1.0.0 // indirect
+ github.com/leodido/go-urn v1.2.1 // indirect
+ github.com/magiconair/properties v1.8.6 // indirect
+ github.com/mattn/go-runewidth v0.0.13 // indirect
+ github.com/mitchellh/mapstructure v1.5.0 // indirect
+ github.com/pelletier/go-toml v1.9.5 // indirect
+ github.com/pelletier/go-toml/v2 v2.0.1 // indirect
+ github.com/pmezard/go-difflib v1.0.0 // indirect
+ github.com/rivo/uniseg v0.2.0 // indirect
+ github.com/russross/blackfriday/v2 v2.0.1 // indirect
+ github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect
+ github.com/spf13/afero v1.8.2 // indirect
+ github.com/spf13/cast v1.5.0 // indirect
+ github.com/spf13/jwalterweatherman v1.1.0 // indirect
+ github.com/spf13/pflag v1.0.5 // indirect
+ github.com/subosito/gotenv v1.3.0 // indirect
+ github.com/tidwall/match v1.1.1 // indirect
+ github.com/tidwall/pretty v1.2.0 // indirect
+ golang.org/x/sys v0.15.0 // indirect
+ golang.org/x/term v0.15.0 // indirect
+ golang.org/x/text v0.14.0 // indirect
+ gopkg.in/ini.v1 v1.66.4 // indirect
+ gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
diff --git a/main.go b/main.go
index 7c2e02698..2ddc4abe9 100644
--- a/main.go
+++ b/main.go
@@ -75,7 +75,7 @@ func main() {
// Setting config
setting := settings.NewSettings()
config := setting.SetupConfig(true, "Copyright (c) 2017-"+
- fmt.Sprint(time.Now().Year())+" The Elastos Foundation", nodePrefix+Version+GoVersion)
+ fmt.Sprint(time.Now().Year())+" The Elastos Foundation", nodePrefix+Version+" "+GoVersion)
// Use all processor cores.
runtime.GOMAXPROCS(runtime.NumCPU())
diff --git a/mempool/conflictfunc.go b/mempool/conflictfunc.go
index b32ea6ebf..5fccefbf2 100644
--- a/mempool/conflictfunc.go
+++ b/mempool/conflictfunc.go
@@ -220,17 +220,45 @@ func strCancelProducerOwnerPublicKey(tx interfaces.Transaction) (interface{},
"cancel producer payload cast failed, tx:%s", tx.Hash())
return nil, errors.Simple(errors.ErrTxPoolFailure, err)
}
- return common.BytesToHexString(p.OwnerPublicKey), nil
+ return common.BytesToHexString(p.OwnerKey), nil
}
-func strActivateAndCancelKeys(tx interfaces.Transaction) (interface{},
+func strActivateKey(tx interfaces.Transaction) (interface{},
error) {
- if tx.TxType() != common2.CancelProducer && tx.TxType() != common2.ActivateProducer {
+ if tx.TxType() != common2.ActivateProducer {
err := fmt.Errorf(
"invalid tx:%s", tx.Hash())
return nil, errors.Simple(errors.ErrTxPoolFailure, err)
}
- return "activatecancel", nil
+ p, ok := tx.Payload().(*payload.ActivateProducer)
+ if !ok {
+ return nil, fmt.Errorf(
+ "activate producer payload cast failed, tx:%s", tx.Hash())
+ }
+ return common.BytesToHexString(p.NodePublicKey), nil
+
+}
+
+func strCancelKey(tx interfaces.Transaction) (interface{},
+ error) {
+ if tx.TxType() != common2.CancelProducer {
+ err := fmt.Errorf(
+ "invalid tx:%s", tx.Hash())
+ return nil, errors.Simple(errors.ErrTxPoolFailure, err)
+ }
+ p, ok := tx.Payload().(*payload.ProcessProducer)
+ if !ok {
+ err := fmt.Errorf(
+ "cancel producer payload cast failed, tx:%s", tx.Hash())
+ return nil, errors.Simple(errors.ErrTxPoolFailure, err)
+ }
+ producer := blockchain.DefaultLedger.Blockchain.GetState().GetProducer(p.OwnerKey)
+ if producer == nil {
+ err := fmt.Errorf(
+ "cancel producer GetProducer(p.OwnerKey) failed, tx:%s", tx.Hash())
+ return nil, errors.Simple(errors.ErrTxPoolFailure, err)
+ }
+ return common.BytesToHexString(producer.NodePublicKey()), nil
}
func strProducerInfoOwnerPublicKey(tx interfaces.Transaction) (interface{}, error) {
@@ -238,7 +266,7 @@ func strProducerInfoOwnerPublicKey(tx interfaces.Transaction) (interface{}, erro
if err != nil {
return nil, err
}
- return common.BytesToHexString(p.OwnerPublicKey), nil
+ return common.BytesToHexString(p.OwnerKey), nil
}
func strProducerInfoNodePublicKey(tx interfaces.Transaction) (interface{}, error) {
@@ -381,7 +409,8 @@ func strRegisterCRPublicKey(tx interfaces.Transaction) (interface{}, error) {
}
var code []byte
- if tx.PayloadVersion() == payload.CRInfoSchnorrVersion {
+ if tx.PayloadVersion() == payload.CRInfoSchnorrVersion ||
+ tx.PayloadVersion() == payload.CRInfoMultiSignVersion {
code = tx.Programs()[0].Code
} else {
code = p.Code
@@ -391,7 +420,9 @@ func strRegisterCRPublicKey(tx interfaces.Transaction) (interface{}, error) {
return nil, err
}
- if signType == vm.CHECKSIG {
+ if signType == vm.CHECKMULTISIG {
+ return hex.EncodeToString(p.Code), nil
+ } else if signType == vm.CHECKSIG {
return hex.EncodeToString(p.Code[1 : len(p.Code)-1]), nil
} else if bytes.Equal(p.Code, []byte{}) && contract.IsSchnorr(code) {
return hex.EncodeToString(code[2:]), nil
@@ -587,7 +618,7 @@ func strDPoSOwnerNodePublicKeys(tx interfaces.Transaction) (interface{}, error)
}
result := make([]string, 0, 2)
- ownerPubkeyStr := common.BytesToHexString(p.OwnerPublicKey)
+ ownerPubkeyStr := common.BytesToHexString(p.OwnerKey)
result = append(result, ownerPubkeyStr)
nodePubkeyStr := common.BytesToHexString(p.NodePublicKey)
diff --git a/mempool/conflictmanager.go b/mempool/conflictmanager.go
index 459e1e050..5301959ab 100644
--- a/mempool/conflictmanager.go
+++ b/mempool/conflictmanager.go
@@ -164,11 +164,11 @@ func newConflictManager() conflictManager {
slot: newConflictSlot(str,
keyTypeFuncPair{
Type: common2.CancelProducer,
- Func: strActivateAndCancelKeys,
+ Func: strCancelKey,
},
keyTypeFuncPair{
Type: common2.ActivateProducer,
- Func: strActivateAndCancelKeys,
+ Func: strActivateKey,
},
),
},
diff --git a/mempool/conflictmanager_test.go b/mempool/conflictmanager_test.go
index 1d19a970b..b0b7137f0 100644
--- a/mempool/conflictmanager_test.go
+++ b/mempool/conflictmanager_test.go
@@ -16,11 +16,13 @@ import (
"github.com/elastos/Elastos.ELA/core/contract"
"github.com/elastos/Elastos.ELA/core/contract/program"
transaction2 "github.com/elastos/Elastos.ELA/core/transaction"
+ "github.com/elastos/Elastos.ELA/core/types"
common2 "github.com/elastos/Elastos.ELA/core/types/common"
"github.com/elastos/Elastos.ELA/core/types/functions"
"github.com/elastos/Elastos.ELA/core/types/interfaces"
"github.com/elastos/Elastos.ELA/core/types/payload"
"github.com/elastos/Elastos.ELA/crypto"
+ "github.com/elastos/Elastos.ELA/dpos/state"
"github.com/stretchr/testify/assert"
)
@@ -40,9 +42,9 @@ func TestConflictManager_DPoS_OwnerPublicKey(t *testing.T) {
common2.RegisterProducer,
0,
&payload.ProducerInfo{
- OwnerPublicKey: pk,
- NodePublicKey: randomPublicKey(),
- NickName: randomNickname(),
+ OwnerKey: pk,
+ NodePublicKey: randomPublicKey(),
+ NickName: randomNickname(),
},
[]*common2.Attribute{},
[]*common2.Input{},
@@ -56,9 +58,22 @@ func TestConflictManager_DPoS_OwnerPublicKey(t *testing.T) {
common2.UpdateProducer,
0,
&payload.ProducerInfo{
- OwnerPublicKey: pk,
- NodePublicKey: randomPublicKey(),
- NickName: randomNickname(),
+ OwnerKey: pk,
+ NodePublicKey: randomPublicKey(),
+ NickName: randomNickname(),
+ },
+ []*common2.Attribute{},
+ []*common2.Input{},
+ []*common2.Output{},
+ 0,
+ []*program.Program{},
+ )
+ tx4 := functions.CreateTransaction(
+ 0,
+ common2.RegisterCR,
+ 0,
+ &payload.CRInfo{
+ Code: redeemScriptFromPk(pk),
},
[]*common2.Attribute{},
[]*common2.Input{},
@@ -67,12 +82,76 @@ func TestConflictManager_DPoS_OwnerPublicKey(t *testing.T) {
[]*program.Program{},
)
- tx3 := functions.CreateTransaction(
+ txs := []interfaces.Transaction{tx1, tx2, tx4} //tx3,
+ verifyTxListWithConflictManager(txs, db, true, t)
+ })
+
+ conflictTestProc(func(db *UtxoCacheDB) {
+ currentHeight := uint32(1)
+ dposState := blockchain.DefaultLedger.Blockchain.GetState()
+ ownerPK1 := randomPublicKey()
+ NodePublicKey1 := randomPublicKey()
+ ownerPK2 := randomPublicKey()
+ NodePublicKey2 := randomPublicKey()
+ regProTX1 := functions.CreateTransaction(
+ 0,
+ common2.RegisterProducer,
+ 0,
+ &payload.ProducerInfo{
+ OwnerKey: ownerPK1,
+ NodePublicKey: NodePublicKey1,
+ NickName: randomNickname(),
+ },
+ []*common2.Attribute{},
+ []*common2.Input{},
+ []*common2.Output{},
+ 0,
+ []*program.Program{},
+ )
+ regProTX2 := functions.CreateTransaction(
+ 0,
+ common2.RegisterProducer,
+ 0,
+ &payload.ProducerInfo{
+ OwnerKey: ownerPK2,
+ NodePublicKey: NodePublicKey2,
+ NickName: randomNickname(),
+ },
+ []*common2.Attribute{},
+ []*common2.Input{},
+ []*common2.Output{},
+ 0,
+ []*program.Program{},
+ )
+ block := &types.Block{
+ Transactions: []interfaces.Transaction{
+ regProTX1,
+ regProTX2,
+ },
+ Header: common2.Header{Height: currentHeight},
+ }
+ dposState.ProcessBlock(block, nil, 0)
+ currentHeight++
+
+ CancelProTX1 := functions.CreateTransaction(
+ 0,
+ common2.CancelProducer,
+ 0,
+ &payload.ProcessProducer{
+ OwnerKey: ownerPK1,
+ },
+ []*common2.Attribute{},
+ []*common2.Input{},
+ []*common2.Output{},
+ 0,
+ []*program.Program{},
+ )
+ CancelProTX2 := functions.CreateTransaction(
0,
common2.CancelProducer,
0,
&payload.ProcessProducer{
- OwnerPublicKey: pk,
+ OwnerKey: ownerPK2,
},
[]*common2.Attribute{},
[]*common2.Input{},
@@ -81,12 +160,12 @@ func TestConflictManager_DPoS_OwnerPublicKey(t *testing.T) {
[]*program.Program{},
)
- tx4 := functions.CreateTransaction(
+ activProTX1 := functions.CreateTransaction(
0,
- common2.RegisterCR,
+ common2.ActivateProducer,
0,
- &payload.CRInfo{
- Code: redeemScriptFromPk(pk),
+ &payload.ActivateProducer{
+ NodePublicKey: NodePublicKey1,
},
[]*common2.Attribute{},
[]*common2.Input{},
@@ -94,9 +173,74 @@ func TestConflictManager_DPoS_OwnerPublicKey(t *testing.T) {
0,
[]*program.Program{},
)
+ activProTX2 := functions.CreateTransaction(
+ 0,
+ common2.ActivateProducer,
+ 0,
+ &payload.ActivateProducer{
+ NodePublicKey: NodePublicKey2,
+ },
+ []*common2.Attribute{},
+ []*common2.Input{},
+ []*common2.Output{},
+ 0,
+ []*program.Program{},
+ )
+ //register two different producer at the same time
+ {
+ manager := newConflictManager()
+ assert.NoError(t, manager.VerifyTx(regProTX1))
+ assert.NoError(t, manager.AppendTx(regProTX1))
+ assert.NoError(t, manager.VerifyTx(regProTX2))
+ assert.NoError(t, manager.AppendTx(regProTX2))
+ }
+ //activate two different producers at the same time
+ {
+ manager := newConflictManager()
+ assert.NoError(t, manager.VerifyTx(activProTX1))
+ assert.NoError(t, manager.AppendTx(activProTX1))
+ assert.NoError(t, manager.VerifyTx(activProTX2))
+ assert.NoError(t, manager.AppendTx(activProTX2))
+ }
+ //activate two different producers at the same time
+ {
+ manager := newConflictManager()
+ assert.NoError(t, manager.VerifyTx(activProTX1))
+ assert.NoError(t, manager.AppendTx(activProTX1))
+ assert.NoError(t, manager.VerifyTx(activProTX2))
+ assert.NoError(t, manager.AppendTx(activProTX2))
+ }
+
+ //cancel two different producers at the same time
+ {
+ manager := newConflictManager()
+ assert.NoError(t, manager.VerifyTx(CancelProTX1))
+ assert.NoError(t, manager.AppendTx(CancelProTX1))
+ assert.NoError(t, manager.VerifyTx(CancelProTX2))
+ assert.NoError(t, manager.AppendTx(CancelProTX2))
+ }
+
+ //active and cancel one producer at the same time must report error
+ {
+ manager := newConflictManager()
+ assert.NoError(t, manager.VerifyTx(CancelProTX1))
+ assert.NoError(t, manager.AppendTx(CancelProTX1))
+ //assert.NoError(t, manager.VerifyTx(activProTX1))
+ err := manager.VerifyTx(activProTX1)
+ assert.Error(t, err, "slot DPoSActivateCancel verify tx error")
+ //no need append
+ //assert.NoError(t, manager.AppendTx(activProTX1))
+ }
+
+ //active and cancel diffrent producers at the same time
+ {
+ manager := newConflictManager()
+ assert.NoError(t, manager.VerifyTx(CancelProTX1))
+ assert.NoError(t, manager.AppendTx(CancelProTX1))
+ assert.NoError(t, manager.VerifyTx(activProTX2))
+ assert.NoError(t, manager.AppendTx(activProTX2))
+ }
- txs := []interfaces.Transaction{tx1, tx2, tx3, tx4}
- verifyTxListWithConflictManager(txs, db, true, t)
})
}
@@ -109,9 +253,9 @@ func TestConflictManager_DPoS_NodePublicKey(t *testing.T) {
common2.RegisterProducer,
0,
&payload.ProducerInfo{
- OwnerPublicKey: randomPublicKey(),
- NodePublicKey: pk,
- NickName: randomNickname(),
+ OwnerKey: randomPublicKey(),
+ NodePublicKey: pk,
+ NickName: randomNickname(),
},
[]*common2.Attribute{},
[]*common2.Input{},
@@ -125,9 +269,9 @@ func TestConflictManager_DPoS_NodePublicKey(t *testing.T) {
common2.UpdateProducer,
0,
&payload.ProducerInfo{
- OwnerPublicKey: randomPublicKey(),
- NodePublicKey: pk,
- NickName: randomNickname(),
+ OwnerKey: randomPublicKey(),
+ NodePublicKey: pk,
+ NickName: randomNickname(),
},
[]*common2.Attribute{},
[]*common2.Input{},
@@ -178,9 +322,9 @@ func TestConflictManager_DPoS_Nickname(t *testing.T) {
common2.RegisterProducer,
0,
&payload.ProducerInfo{
- OwnerPublicKey: randomPublicKey(),
- NodePublicKey: randomPublicKey(),
- NickName: name,
+ OwnerKey: randomPublicKey(),
+ NodePublicKey: randomPublicKey(),
+ NickName: name,
},
[]*common2.Attribute{},
[]*common2.Input{},
@@ -194,9 +338,9 @@ func TestConflictManager_DPoS_Nickname(t *testing.T) {
common2.UpdateProducer,
0,
&payload.ProducerInfo{
- OwnerPublicKey: randomPublicKey(),
- NodePublicKey: randomPublicKey(),
- NickName: name,
+ OwnerKey: randomPublicKey(),
+ NodePublicKey: randomPublicKey(),
+ NickName: name,
},
[]*common2.Attribute{},
[]*common2.Input{},
@@ -696,9 +840,9 @@ func TestConflictManager_InputInferKeys(t *testing.T) {
common2.RegisterProducer,
0,
&payload.ProducerInfo{
- OwnerPublicKey: randomPublicKey(),
- NodePublicKey: randomPublicKey(),
- NickName: randomNickname(),
+ OwnerKey: randomPublicKey(),
+ NodePublicKey: randomPublicKey(),
+ NickName: randomNickname(),
},
[]*common2.Attribute{},
[]*common2.Input{},
@@ -712,9 +856,9 @@ func TestConflictManager_InputInferKeys(t *testing.T) {
common2.UpdateProducer,
0,
&payload.ProducerInfo{
- OwnerPublicKey: randomPublicKey(),
- NodePublicKey: randomPublicKey(),
- NickName: randomNickname(),
+ OwnerKey: randomPublicKey(),
+ NodePublicKey: randomPublicKey(),
+ NickName: randomNickname(),
},
[]*common2.Attribute{},
[]*common2.Input{},
@@ -722,21 +866,6 @@ func TestConflictManager_InputInferKeys(t *testing.T) {
0,
[]*program.Program{},
)
-
- tx3 := functions.CreateTransaction(
- 0,
- common2.CancelProducer,
- 0,
- &payload.ProcessProducer{
- OwnerPublicKey: randomPublicKey(),
- },
- []*common2.Attribute{},
- []*common2.Input{},
- []*common2.Output{},
- 0,
- []*program.Program{},
- )
-
tx4 := functions.CreateTransaction(
0,
common2.RegisterCR,
@@ -894,8 +1023,7 @@ func TestConflictManager_InputInferKeys(t *testing.T) {
0,
[]*program.Program{},
)
-
- txs := []interfaces.Transaction{tx1, tx2, tx3, tx4, tx5, tx6, tx7, tx8, tx9, tx10, tx11, tx12, tx13, tx14}
+ txs := []interfaces.Transaction{tx1, tx2, tx4, tx5, tx6, tx7, tx8, tx9, tx10, tx11, tx12, tx13, tx14}
verifyTxListWithConflictManager(txs, db, false, t)
})
@@ -909,6 +1037,20 @@ func conflictTestProc(action func(*UtxoCacheDB)) {
UTXOCache: blockchain.NewUTXOCache(utxoCacheDB, &config.DefaultParams),
},
}
+
+ blockchain.DefaultLedger.Blockchain.SetState(state.NewState(&config.DefaultParams, nil, nil, nil,
+ func() bool { return false }, func(programHash common.Uint168) (common.Fixed64,
+ error) {
+ amount := common.Fixed64(0)
+ utxos, err := blockchain.DefaultLedger.Blockchain.GetDB().GetFFLDB().GetUTXO(&programHash)
+ if err != nil {
+ return amount, err
+ }
+ for _, utxo := range utxos {
+ amount += utxo.Value
+ }
+ return amount, nil
+ }, nil, nil, nil, nil, nil, nil))
action(utxoCacheDB)
blockchain.DefaultLedger = origin
}
diff --git a/mempool/txpool.go b/mempool/txpool.go
index 378b3191b..ed7aaf25b 100644
--- a/mempool/txpool.go
+++ b/mempool/txpool.go
@@ -80,8 +80,8 @@ func (mp *TxPool) removeCRAppropriationConflictTransactions() {
}
func (mp *TxPool) appendToTxPool(tx interfaces.Transaction) elaerr.ELAError {
- // todo complete me
- if tx.IsIllegalProposalTx() || tx.IsIllegalVoteTx() || tx.IsRecordSponorTx() {
+
+ if tx.IsRecordSponorTx() {
return elaerr.Simple(elaerr.ErrTxValidation, nil)
}
@@ -328,7 +328,7 @@ func (mp *TxPool) cleanCanceledProducerAndCR(txs []interfaces.Transaction) error
if !ok {
return errors.New("invalid cancel producer payload")
}
- if err := mp.cleanVoteAndUpdateProducer(cpPayload.OwnerPublicKey); err != nil {
+ if err := mp.cleanVoteAndUpdateProducer(cpPayload.OwnerKey); err != nil {
log.Error(err)
}
}
@@ -398,10 +398,10 @@ func (mp *TxPool) cleanVoteAndUpdateProducer(ownerPublicKey []byte) error {
if !ok {
return errors.New("invalid update producer payload")
}
- if bytes.Equal(upPayload.OwnerPublicKey, ownerPublicKey) {
+ if bytes.Equal(upPayload.OwnerKey, ownerPublicKey) {
mp.removeTransaction(txn)
if err := mp.RemoveKey(
- BytesToHexString(upPayload.OwnerPublicKey),
+ BytesToHexString(upPayload.OwnerKey),
slotDPoSOwnerPublicKey); err != nil {
return err
}
diff --git a/mempool/txpool_test.go b/mempool/txpool_test.go
index 0cde89197..5a02683d7 100644
--- a/mempool/txpool_test.go
+++ b/mempool/txpool_test.go
@@ -326,11 +326,11 @@ func TestTxPool_VerifyDuplicateCRTx(t *testing.T) {
[]*program.Program{},
)
tx5.SetPayload(&payload.ProducerInfo{
- OwnerPublicKey: publicKey1,
- NodePublicKey: publicKey2,
- NickName: "nickname 3",
- Url: "http://www.elastos_test.com",
- Location: 3,
+ OwnerKey: publicKey1,
+ NodePublicKey: publicKey2,
+ NickName: "nickname 3",
+ Url: "http://www.elastos_test.com",
+ Location: 3,
})
tx5.SetInputs([]*common2.Input{input3})
@@ -346,11 +346,11 @@ func TestTxPool_VerifyDuplicateCRTx(t *testing.T) {
[]*program.Program{},
)
tx6.SetPayload(&payload.ProducerInfo{
- OwnerPublicKey: publicKey2,
- NodePublicKey: publicKey1,
- NickName: "nickname 4",
- Url: "http://www.elastos_test.com",
- Location: 4,
+ OwnerKey: publicKey2,
+ NodePublicKey: publicKey1,
+ NickName: "nickname 4",
+ Url: "http://www.elastos_test.com",
+ Location: 4,
})
tx6.SetInputs([]*common2.Input{input4})
diff --git a/mempool/txpoolcheckpoint.go b/mempool/txpoolcheckpoint.go
index 10e7b9717..0f2204998 100644
--- a/mempool/txpoolcheckpoint.go
+++ b/mempool/txpoolcheckpoint.go
@@ -122,6 +122,10 @@ func (c *txPoolCheckpoint) OnInit() {
c.initConflictManager(c.txnList)
}
+func (c *txPoolCheckpoint) SaveStartHeight() uint32 {
+ return uint32(1)
+}
+
func (c *txPoolCheckpoint) StartHeight() uint32 {
return uint32(1)
}
diff --git a/pow/revertlistener.go b/pow/revertlistener.go
index f891aef6c..d0ca7b3d8 100644
--- a/pow/revertlistener.go
+++ b/pow/revertlistener.go
@@ -21,7 +21,8 @@ func (pow *Service) ListenForRevert() {
go func() {
for {
time.Sleep(CheckRevertToPOWInterval)
- if pow.chain.BestChain.Height < pow.chainParams.DPoSConfiguration.RevertToPOWStartHeight {
+ currentHeight := pow.chain.BestChain.Height
+ if currentHeight < pow.chainParams.DPoSConfiguration.RevertToPOWStartHeight {
continue
}
if pow.arbiters.IsInPOWMode() {
@@ -29,9 +30,16 @@ func (pow *Service) ListenForRevert() {
}
lastBlockTimestamp := int64(pow.arbiters.GetLastBlockTimestamp())
localTimestamp := pow.chain.TimeSource.AdjustedTime().Unix()
- log.Info("ListenForRevert lastBlockTimestamp:", lastBlockTimestamp,
- "localTimestamp:", localTimestamp, "RevertToPOWNoBlockTime:", pow.chainParams.DPoSConfiguration.RevertToPOWNoBlockTime)
- if localTimestamp-lastBlockTimestamp < pow.chainParams.DPoSConfiguration.RevertToPOWNoBlockTime {
+ var noBlockTime int64
+ if currentHeight < pow.chainParams.DPoSConfiguration.ChangeViewV1Height {
+ noBlockTime = pow.chainParams.DPoSConfiguration.RevertToPOWNoBlockTime
+ } else {
+ noBlockTime = pow.chainParams.DPoSConfiguration.RevertToPOWNoBlockTimeV1
+ }
+
+ log.Debug("ListenForRevert lastBlockTimestamp:", lastBlockTimestamp,
+ "localTimestamp:", localTimestamp, "RevertToPOWNoBlockTime:", noBlockTime)
+ if localTimestamp-lastBlockTimestamp < noBlockTime {
continue
}
diff --git a/pow/service.go b/pow/service.go
index cb28d5019..2e10ba79c 100644
--- a/pow/service.go
+++ b/pow/service.go
@@ -38,7 +38,6 @@ const (
maxNonce = ^uint32(0) // 2^32 - 1
updateInterval = 30 * time.Second
createAuxBlockInterval = 5 * time.Second
- maxTxPerBlock = 100
)
type Config struct {
@@ -277,7 +276,7 @@ func (pow *Service) distributeDPOSReward(coinBaseTx interfaces.Transaction,
}
func (pow *Service) GenerateBlock(minerAddr string,
- txPerBlock int) (*types.Block, error) {
+ txPerBlock uint32) (*types.Block, error) {
bestChain := pow.chain.BestChain
nextBlockHeight := bestChain.Height + 1
coinBaseTx, err := pow.CreateCoinbaseTx(minerAddr, nextBlockHeight)
@@ -300,6 +299,9 @@ func (pow *Service) GenerateBlock(minerAddr string,
}
msgBlock.Transactions = append(msgBlock.Transactions, coinBaseTx)
+ txCount := uint32(1)
+ totalTxsSize := coinBaseTx.GetSize()
+ totalTxFee := common.Fixed64(0)
if bestChain.Height+1 >= pow.chainParams.DPoSConfiguration.RecordSponsorStartHeight {
bestBlock, err := pow.chain.GetDposBlockByHash(*bestChain.Hash)
@@ -312,14 +314,12 @@ func (pow *Service) GenerateBlock(minerAddr string,
return nil, err
}
msgBlock.Transactions = append(msgBlock.Transactions, recordSponsorTx)
+ txCount++
+ totalTxsSize += recordSponsorTx.GetSize()
}
}
- totalTxsSize := coinBaseTx.GetSize()
- txCount := 1
- totalTxFee := common.Fixed64(0)
txs := pow.txMemPool.GetTxsInPool()
-
isHighPriority := func(tx interfaces.Transaction) bool {
if tx.IsRevertToPOW() || tx.IsRevertToDPOS() ||
tx.IsIllegalTypeTx() || tx.IsInactiveArbitrators() ||
@@ -344,8 +344,7 @@ func (pow *Service) GenerateBlock(minerAddr string,
var proposalsUsedAmount common.Fixed64
for _, tx := range txs {
-
- if tx.IsIllegalProposalTx() || tx.IsIllegalVoteTx() || tx.IsRecordSponorTx() {
+ if tx.IsRecordSponorTx() {
continue
}
@@ -403,7 +402,7 @@ func (pow *Service) CreateAuxBlock(payToAddr string) (*types.Block, error) {
}
// Create new block with nonce = 0
- auxBlock, err := pow.GenerateBlock(payToAddr, maxTxPerBlock)
+ auxBlock, err := pow.GenerateBlock(payToAddr, pact.MaxTxPerBlock)
if err != nil {
return nil, err
}
@@ -463,7 +462,7 @@ func (pow *Service) DiscreteMining(n uint32) ([]*common.Uint256, error) {
log.Info("<================Discrete Mining==============>\n")
for {
- msgBlock, err := pow.GenerateBlock(pow.PayToAddr, maxTxPerBlock)
+ msgBlock, err := pow.GenerateBlock(pow.PayToAddr, pact.MaxTxPerBlock)
if err != nil {
log.Warn("Generate block failed, ", err.Error())
continue
@@ -572,7 +571,7 @@ out:
log.Debug("<================Packing Block==============>")
//time.Sleep(15 * time.Second)
- msgBlock, err := pow.GenerateBlock(pow.PayToAddr, maxTxPerBlock)
+ msgBlock, err := pow.GenerateBlock(pow.PayToAddr, pact.MaxTxPerBlock)
if err != nil {
log.Debug("generage block err", err)
continue
diff --git a/servers/common.go b/servers/common.go
index c054609f4..7c4573f25 100644
--- a/servers/common.go
+++ b/servers/common.go
@@ -264,6 +264,14 @@ type CRInfo struct {
Signature string `json:"signature"`
}
+type MultiCRInfo struct {
+ CID string `json:"cid"`
+ DID string `json:"did"`
+ NickName string `json:"nickname"`
+ Url string `json:"url"`
+ Location uint64 `json:"location"`
+}
+
type UnregisterCRInfo struct {
CID string `json:"cid"`
Signature string `json:"signature"`
@@ -442,6 +450,13 @@ type NextTurnDPOSPayloadInfo struct {
DPOSPublicKeys []string `json:"dpospublickeys"`
}
+type NextTurnDPOSPayloadInfoV2 struct {
+ WorkingHeight uint32 `json:"workingheight"`
+ CRPublicKeys []string `json:"crpublickeys"`
+ DPOSPublicKeys []string `json:"dpospublickeys"`
+ CompleteCRPublicKeys []string `json:"CompleteCRPublicKeys"`
+}
+
type CRCProposalRealWithdrawInfo struct {
WithdrawTransactionHashes []string `json:"withdrawtransactionhashes"`
}
@@ -594,12 +609,36 @@ type DposV2ClaimRewardRealWithdrawInfo struct {
}
type CreateNFTInfo struct {
- // nft id, hash of detailed vote information.
+ // NFT ID
+ ID string
+ // hash of detailed vote information.
+ ReferKey string
+ // side chain format address.
+ StakeAddress string
+ // side chain genesis block address
+ GenesisBlockHash string
+}
+
+type CreateNFTInfoV2 struct {
+ // NFT ID
ID string
+ // hash of detailed vote information.
+ ReferKey string
// side chain format address.
StakeAddress string
// side chain genesis block address
GenesisBlockHash string
+ // the start height of votes
+ StartHeight uint32
+ // the end height of votes: start height + lock time.
+ EndHeight uint32
+ // the DPoS 2.0 votes.
+ Votes string
+ // the DPoS 2.0 vote rights.
+ VoteRights string
+ // the votes to the producer, and TargetOwnerPublicKey is the producer's
+ // owner key.
+ TargetOwnerKey string
}
type DestroyNFTInfo struct {
diff --git a/servers/interfaces.go b/servers/interfaces.go
index 4f3354f3d..ccb5ec91d 100644
--- a/servers/interfaces.go
+++ b/servers/interfaces.go
@@ -100,7 +100,7 @@ func GetTransactionInfo(tx interfaces.Transaction) *TransactionInfo {
Version: tx.Version(),
TxType: tx.TxType(),
PayloadVersion: tx.PayloadVersion(),
- Payload: getPayloadInfo(tx.Payload(), tx.PayloadVersion()),
+ Payload: getPayloadInfo(tx, tx.PayloadVersion()),
Attributes: attributes,
Inputs: inputs,
Outputs: outputs,
@@ -562,16 +562,13 @@ func GetProducerInfo(params Params) map[string]interface{} {
if err != nil {
return ResponsePack(InvalidParams, "invalid public key")
}
- if _, err = contract.PublicKeyToStandardProgramHash(publicKeyBytes); err != nil {
- return ResponsePack(InvalidParams, "invalid public key bytes")
- }
p := Chain.GetState().GetProducer(publicKeyBytes)
if p == nil {
return ResponsePack(InvalidParams, "unknown producer public key")
}
producerInfo := RPCProducerInfo{
- OwnerPublicKey: hex.EncodeToString(p.Info().OwnerPublicKey),
+ OwnerPublicKey: hex.EncodeToString(p.Info().OwnerKey),
NodePublicKey: hex.EncodeToString(p.Info().NodePublicKey),
Nickname: p.Info().NickName,
Url: p.Info().Url,
@@ -2110,7 +2107,7 @@ type RPCProducerInfo struct {
Index uint64 `json:"index"`
}
-//a group producer info include TotalDPoSV1Votes and producer count
+// a group producer info include TotalDPoSV1Votes and producer count
type RPCProducersInfo struct {
ProducerInfoSlice []RPCProducerInfo `json:"producers"`
TotalDPoSV1Votes string `json:"totaldposv1votes"`
@@ -2134,7 +2131,7 @@ type RPCCRCandidateInfo struct {
Index uint64 `json:"index"`
}
-//a group cr candidate info include TotalDPoSV1Votes and candidate count
+// a group cr candidate info include TotalDPoSV1Votes and candidate count
type RPCCRCandidatesInfo struct {
CRCandidateInfoSlice []RPCCRCandidateInfo `json:"crcandidatesinfo"`
TotalVotes string `json:"totalvotes"`
@@ -2423,7 +2420,7 @@ func ListProducers(param Params) map[string]interface{} {
totalVotes += p.Votes()
totalDPoSV2Votes += common.Fixed64(p.GetTotalDPoSV2VoteRights())
producerInfo := RPCProducerInfo{
- OwnerPublicKey: hex.EncodeToString(p.Info().OwnerPublicKey),
+ OwnerPublicKey: hex.EncodeToString(p.Info().OwnerKey),
NodePublicKey: hex.EncodeToString(p.Info().NodePublicKey),
Nickname: p.Info().NickName,
Url: p.Info().Url,
@@ -3010,9 +3007,6 @@ func ProducerStatus(param Params) map[string]interface{} {
if err != nil {
return ResponsePack(InvalidParams, "invalid public key")
}
- if _, err = contract.PublicKeyToStandardProgramHash(publicKeyBytes); err != nil {
- return ResponsePack(InvalidParams, "invalid public key bytes")
- }
producer := Chain.GetState().GetProducer(publicKeyBytes)
if producer == nil {
return ResponsePack(InvalidParams, "unknown producer public key")
@@ -3216,7 +3210,8 @@ func DecodeRawTransaction(param Params) map[string]interface{} {
return ResponsePack(Success, GetTransactionInfo(txn))
}
-func getPayloadInfo(p interfaces.Payload, payloadVersion byte) PayloadInfo {
+func getPayloadInfo(tx interfaces.Transaction, payloadVersion byte) PayloadInfo {
+ p := tx.Payload()
switch object := p.(type) {
case *payload.CoinBase:
obj := new(CoinbaseInfo)
@@ -3270,7 +3265,7 @@ func getPayloadInfo(p interfaces.Payload, payloadVersion byte) PayloadInfo {
case *payload.Record:
case *payload.ProducerInfo:
obj := new(ProducerInfo)
- obj.OwnerPublicKey = common.BytesToHexString(object.OwnerPublicKey)
+ obj.OwnerPublicKey = common.BytesToHexString(object.OwnerKey)
obj.NodePublicKey = common.BytesToHexString(object.NodePublicKey)
obj.NickName = object.NickName
obj.Url = object.Url
@@ -3281,7 +3276,7 @@ func getPayloadInfo(p interfaces.Payload, payloadVersion byte) PayloadInfo {
return obj
case *payload.ProcessProducer:
obj := new(CancelProducerInfo)
- obj.OwnerPublicKey = common.BytesToHexString(object.OwnerPublicKey)
+ obj.OwnerPublicKey = common.BytesToHexString(object.OwnerKey)
obj.Signature = common.BytesToHexString(object.Signature)
return obj
case *payload.InactiveArbitrators:
@@ -3314,21 +3309,40 @@ func getPayloadInfo(p interfaces.Payload, payloadVersion byte) PayloadInfo {
obj.EndHeight = object.EndHeight
return obj
case *payload.CRInfo:
- obj := new(CRInfo)
- obj.Code = common.BytesToHexString(object.Code)
- cid, _ := object.CID.ToAddress()
- obj.CID = cid
- did, _ := object.DID.ToAddress()
- if object.DID.IsEqual(emptyHash) {
- obj.DID = ""
- } else {
- obj.DID = did
+ switch payloadVersion {
+ case payload.CRInfoSchnorrVersion, payload.CRInfoMultiSignVersion:
+ obj := new(MultiCRInfo)
+ cid, _ := object.CID.ToAddress()
+ obj.CID = cid
+ did, _ := object.DID.ToAddress()
+ if object.DID.IsEqual(emptyHash) {
+ obj.DID = ""
+ } else {
+ obj.DID = did
+ }
+ obj.NickName = object.NickName
+ obj.Url = object.Url
+ obj.Location = object.Location
+ return obj
+
+ default:
+ obj := new(CRInfo)
+ obj.Code = common.BytesToHexString(object.Code)
+ cid, _ := object.CID.ToAddress()
+ obj.CID = cid
+ did, _ := object.DID.ToAddress()
+ if object.DID.IsEqual(emptyHash) {
+ obj.DID = ""
+ } else {
+ obj.DID = did
+ }
+ obj.NickName = object.NickName
+ obj.Url = object.Url
+ obj.Location = object.Location
+ obj.Signature = common.BytesToHexString(object.Signature)
+ return obj
}
- obj.NickName = object.NickName
- obj.Url = object.Url
- obj.Location = object.Location
- obj.Signature = common.BytesToHexString(object.Signature)
- return obj
+
case *payload.UnregisterCR:
obj := new(UnregisterCRInfo)
cid, _ := object.CID.ToAddress()
@@ -3350,7 +3364,7 @@ func getPayloadInfo(p interfaces.Payload, payloadVersion byte) PayloadInfo {
obj := new(CRCProposalInfo)
obj.ProposalType = object.ProposalType.Name()
obj.CategoryData = object.CategoryData
- obj.OwnerPublicKey = common.BytesToHexString(object.OwnerPublicKey)
+ obj.OwnerPublicKey = common.BytesToHexString(object.OwnerKey)
obj.DraftHash = common.ToReversedString(object.DraftHash)
obj.Budgets = budgets
addr, _ := object.Recipient.ToAddress()
@@ -3366,12 +3380,12 @@ func getPayloadInfo(p interfaces.Payload, payloadVersion byte) PayloadInfo {
obj := new(CRCChangeProposalOwnerInfo)
obj.ProposalType = object.ProposalType.Name()
obj.CategoryData = object.CategoryData
- obj.OwnerPublicKey = common.BytesToHexString(object.OwnerPublicKey)
+ obj.OwnerPublicKey = common.BytesToHexString(object.OwnerKey)
obj.DraftHash = common.ToReversedString(object.DraftHash)
obj.TargetProposalHash = common.ToReversedString(object.TargetProposalHash)
addr, _ := object.NewRecipient.ToAddress()
obj.NewRecipient = addr
- obj.NewOwnerPublicKey = common.BytesToHexString(object.NewOwnerPublicKey)
+ obj.NewOwnerPublicKey = common.BytesToHexString(object.NewOwnerKey)
obj.Signature = common.BytesToHexString(object.Signature)
obj.NewOwnerSignature = common.BytesToHexString(object.NewOwnerSignature)
crmdid, _ := object.CRCouncilMemberDID.ToAddress()
@@ -3384,7 +3398,7 @@ func getPayloadInfo(p interfaces.Payload, payloadVersion byte) PayloadInfo {
obj := new(CRCCloseProposalInfo)
obj.ProposalType = object.ProposalType.Name()
obj.CategoryData = object.CategoryData
- obj.OwnerPublicKey = common.BytesToHexString(object.OwnerPublicKey)
+ obj.OwnerPublicKey = common.BytesToHexString(object.OwnerKey)
obj.DraftHash = common.ToReversedString(object.DraftHash)
obj.TargetProposalHash = common.ToReversedString(object.TargetProposalHash)
obj.Signature = common.BytesToHexString(object.Signature)
@@ -3398,7 +3412,7 @@ func getPayloadInfo(p interfaces.Payload, payloadVersion byte) PayloadInfo {
obj := new(CRCReservedCustomIDProposalInfo)
obj.ProposalType = object.ProposalType.Name()
obj.CategoryData = object.CategoryData
- obj.OwnerPublicKey = common.BytesToHexString(object.OwnerPublicKey)
+ obj.OwnerPublicKey = common.BytesToHexString(object.OwnerKey)
obj.DraftHash = common.ToReversedString(object.DraftHash)
obj.ReservedCustomIDList = object.ReservedCustomIDList
obj.Signature = common.BytesToHexString(object.Signature)
@@ -3412,7 +3426,7 @@ func getPayloadInfo(p interfaces.Payload, payloadVersion byte) PayloadInfo {
obj := new(CRCReceivedCustomIDProposalInfo)
obj.ProposalType = object.ProposalType.Name()
obj.CategoryData = object.CategoryData
- obj.OwnerPublicKey = common.BytesToHexString(object.OwnerPublicKey)
+ obj.OwnerPublicKey = common.BytesToHexString(object.OwnerKey)
obj.DraftHash = common.ToReversedString(object.DraftHash)
obj.ReceiveCustomIDList = object.ReceivedCustomIDList
obj.ReceiverDID, _ = object.ReceiverDID.ToAddress()
@@ -3427,7 +3441,7 @@ func getPayloadInfo(p interfaces.Payload, payloadVersion byte) PayloadInfo {
obj := new(CRCChangeCustomIDFeeInfo)
obj.ProposalType = object.ProposalType.Name()
obj.CategoryData = object.CategoryData
- obj.OwnerPublicKey = common.BytesToHexString(object.OwnerPublicKey)
+ obj.OwnerPublicKey = common.BytesToHexString(object.OwnerKey)
obj.DraftHash = common.ToReversedString(object.DraftHash)
obj.FeeRate = int64(object.RateOfCustomIDFee)
obj.EIDEffectiveHeight = object.EIDEffectiveHeight
@@ -3442,7 +3456,7 @@ func getPayloadInfo(p interfaces.Payload, payloadVersion byte) PayloadInfo {
obj := new(CRCSecretaryGeneralProposalInfo)
obj.ProposalType = object.ProposalType.Name()
obj.CategoryData = object.CategoryData
- obj.OwnerPublicKey = common.BytesToHexString(object.OwnerPublicKey)
+ obj.OwnerPublicKey = common.BytesToHexString(object.OwnerKey)
obj.DraftHash = common.ToReversedString(object.DraftHash)
obj.SecretaryGeneralPublicKey = common.BytesToHexString(object.SecretaryGeneralPublicKey)
sgDID, _ := object.SecretaryGeneralDID.ToAddress()
@@ -3459,7 +3473,7 @@ func getPayloadInfo(p interfaces.Payload, payloadVersion byte) PayloadInfo {
obj := new(CRCRegisterSideChainProposalInfo)
obj.ProposalType = object.ProposalType.Name()
obj.CategoryData = object.CategoryData
- obj.OwnerPublicKey = common.BytesToHexString(object.OwnerPublicKey)
+ obj.OwnerPublicKey = common.BytesToHexString(object.OwnerKey)
obj.DraftHash = common.ToReversedString(object.DraftHash)
obj.SideChainName = object.SideChainName
obj.MagicNumber = object.MagicNumber
@@ -3504,10 +3518,10 @@ func getPayloadInfo(p interfaces.Payload, payloadVersion byte) PayloadInfo {
obj.ProposalHash = common.ToReversedString(object.ProposalHash)
obj.MessageHash = common.ToReversedString(object.MessageHash)
obj.Stage = object.Stage
- obj.OwnerPublicKey = common.BytesToHexString(object.OwnerPublicKey)
- obj.NewOwnerPublicKey = common.BytesToHexString(object.NewOwnerPublicKey)
+ obj.OwnerPublicKey = common.BytesToHexString(object.OwnerKey)
+ obj.NewOwnerPublicKey = common.BytesToHexString(object.NewOwnerKey)
obj.OwnerSignature = common.BytesToHexString(object.OwnerSignature)
- obj.NewOwnerPublicKey = common.BytesToHexString(object.NewOwnerPublicKey)
+ obj.NewOwnerPublicKey = common.BytesToHexString(object.NewOwnerKey)
obj.SecretaryGeneralOpinionHash = common.ToReversedString(object.SecretaryGeneralOpinionHash)
obj.SecretaryGeneralSignature = common.BytesToHexString(object.SecretaryGeneralSignature)
obj.NewOwnerSignature = common.BytesToHexString(object.NewOwnerSignature)
@@ -3516,7 +3530,7 @@ func getPayloadInfo(p interfaces.Payload, payloadVersion byte) PayloadInfo {
case *payload.CRCProposalWithdraw:
obj := new(CRCProposalWithdrawInfo)
obj.ProposalHash = common.ToReversedString(object.ProposalHash)
- obj.OwnerPublicKey = common.BytesToHexString(object.OwnerPublicKey)
+ obj.OwnerPublicKey = common.BytesToHexString(object.OwnerKey)
if payloadVersion == payload.CRCProposalWithdrawVersion01 {
recipient, err := object.Recipient.ToAddress()
if err == nil {
@@ -3535,18 +3549,39 @@ func getPayloadInfo(p interfaces.Payload, payloadVersion byte) PayloadInfo {
return obj
case *payload.NextTurnDPOSInfo:
- obj := new(NextTurnDPOSPayloadInfo)
+ if payloadVersion == payload.NextTurnDPOSInfoVersion {
+ obj := new(NextTurnDPOSPayloadInfo)
+ crPublicKeysString := make([]string, 0)
+ dposPublicKeysString := make([]string, 0)
+ for _, v := range object.CRPublicKeys {
+ crPublicKeysString = append(crPublicKeysString, common.BytesToHexString(v))
+ }
+ for _, v := range object.DPOSPublicKeys {
+ dposPublicKeysString = append(dposPublicKeysString, common.BytesToHexString(v))
+ }
+ obj.WorkingHeight = object.WorkingHeight
+ obj.CRPublickeys = crPublicKeysString
+ obj.DPOSPublicKeys = dposPublicKeysString
+ return obj
+ }
+
+ obj := new(NextTurnDPOSPayloadInfoV2)
crPublicKeysString := make([]string, 0)
dposPublicKeysString := make([]string, 0)
+ completeCRPublicKeysString := make([]string, 0)
for _, v := range object.CRPublicKeys {
crPublicKeysString = append(crPublicKeysString, common.BytesToHexString(v))
}
for _, v := range object.DPOSPublicKeys {
dposPublicKeysString = append(dposPublicKeysString, common.BytesToHexString(v))
}
+ for _, v := range object.CompleteCRPublicKeys {
+ completeCRPublicKeysString = append(completeCRPublicKeysString, common.BytesToHexString(v))
+ }
obj.WorkingHeight = object.WorkingHeight
- obj.CRPublickeys = crPublicKeysString
+ obj.CRPublicKeys = crPublicKeysString
obj.DPOSPublicKeys = dposPublicKeysString
+ obj.CompleteCRPublicKeys = completeCRPublicKeysString
return obj
case *payload.CRCProposalRealWithdraw:
@@ -3752,10 +3787,26 @@ func getPayloadInfo(p interfaces.Payload, payloadVersion byte) PayloadInfo {
return obj
case *payload.CreateNFT:
- obj := &CreateNFTInfo{
- ID: object.ReferKey.ReversedString(),
+ if payloadVersion == payload.CreateNFTVersion {
+ obj := &CreateNFTInfo{
+ ID: common.GetNFTID(object.ReferKey, tx.Hash()).ReversedString(),
+ ReferKey: object.ReferKey.ReversedString(),
+ StakeAddress: object.StakeAddress,
+ GenesisBlockHash: common.ToReversedString(object.GenesisBlockHash),
+ }
+ return obj
+ }
+
+ obj := &CreateNFTInfoV2{
+ ID: common.GetNFTID(object.ReferKey, tx.Hash()).ReversedString(),
+ ReferKey: object.ReferKey.ReversedString(),
StakeAddress: object.StakeAddress,
GenesisBlockHash: common.ToReversedString(object.GenesisBlockHash),
+ StartHeight: object.StartHeight,
+ EndHeight: object.EndHeight,
+ Votes: object.Votes.String(),
+ VoteRights: object.VoteRights.String(),
+ TargetOwnerKey: common.BytesToHexString(object.TargetOwnerKey),
}
return obj
diff --git a/test/transaction/cancel_producer_tx.lua b/test/transaction/cancel_producer_tx.lua
index 03af5ba6a..429c291d4 100644
--- a/test/transaction/cancel_producer_tx.lua
+++ b/test/transaction/cancel_producer_tx.lua
@@ -19,9 +19,7 @@ local wallet = client.new(keystore, password, false)
-- account
local addr = wallet:get_address()
-local pubkey = wallet:get_publickey()
print(addr)
-print(pubkey)
-- asset_id
local asset_id = m.get_asset_id()
@@ -41,13 +39,16 @@ then
end
print("owner public key:", own_publickey)
+local payloadversion = getPayloadVersion()
+print("payloadversion:", payloadversion)
+
-- cancel producer payload: publickey, wallet
-local cp_payload = cancelproducer.new(own_publickey, wallet)
+local cp_payload = cancelproducer.new(own_publickey,payloadversion, wallet)
print(cp_payload:get())
-- transaction: version, txType, payloadVersion, payload, locktime
-local tx = transaction.new(9, 0x0a, 0, cp_payload, 0)
+local tx = transaction.new(9, 0x0a, payloadversion, cp_payload, 0)
-- input: from, amount + fee
local charge = tx:appendenough(addr, fee * 100000000)
@@ -62,7 +63,9 @@ tx:appendtxout(charge_output)
-- print(charge_output:get())
-- sign
-tx:sign(wallet)
+--tx:sign(wallet)
+tx:multisign(wallet, 3)
+
print(tx:get())
-- send
diff --git a/test/transaction/exchange_votes_multi_inputs.lua b/test/transaction/exchange_votes_multi_inputs.lua
new file mode 100644
index 000000000..67db48a4e
--- /dev/null
+++ b/test/transaction/exchange_votes_multi_inputs.lua
@@ -0,0 +1,106 @@
+-- Copyright (c) 2017-2020 The Elastos Foundation
+-- Use of this source code is governed by an MIT
+-- license that can be found in the LICENSE file.
+--
+
+local m = require("api")
+
+local keystore = getWallet()
+local password = getPassword()
+
+if keystore == "" then
+ keystore = "keystore.dat"
+end
+if password == "" then
+ password = "123"
+end
+
+local wallet = client.new(keystore, password, false)
+
+--todo add get_addresses
+local addresses = getAddresses()
+-- account
+--local c = wallet:get_address()
+
+--vote for saddr mainaccount addr
+local saddr = wallet:get_s_address()
+print("saddr", saddr)
+
+-- asset_id
+local asset_id = m.get_asset_id()
+local amount = getAmount()
+local fee = getFee()
+
+if amount == 0 then
+ amount = 0.2
+end
+
+if fee == 0 then
+ fee = 0.1
+end
+
+print("address len ", #addresses)
+print("amount ", amount)
+print("fee:", fee)
+
+
+-- transaction payload
+local ta = exchangevotes.new()
+
+-- transaction: version, tx_type, payload_version, payload, locktime
+--define transaction and set tx payload
+local tx = transaction.new(9, 0x62, 0, ta, 0)
+
+--iterate every address, each one vote amount votes
+--stake output
+-- define output payload (vote to saddr)
+local vote_output = stakeoutput.new(0, saddr)
+print("vote_output", vote_output:get())
+--all output to stake_pool for stake
+stake_pool = "SNmCKtp1NmPfjwEo4m8PbgirDfYss1NUyT"
+--define output OTStake = 7
+
+
+
+local amount_output = output.new(asset_id, #addresses*amount * 100000000, stake_pool, 7, vote_output)
+tx:appendtxout(amount_output)
+
+for i, addr in ipairs(addresses) do
+ print(i, addr)
+ -- input: from, amount + fee
+ --append amount + fee input to tx and return charge(change ) aount
+ local tempFee = fee
+ if( i ~= 0 )
+ then
+ tempFee = 0
+ end
+
+ local charge = tx:appendenoughmultiinput(addr, (amount* 100000000 + fee* 100000000) )
+ print("charge", charge)
+
+ ----charge output
+ --define output payload
+ local charge_output_payload = defaultoutput.new()
+ -- output: asset_id, value, recipient, output_paload_type, output_paload
+ local charge_output = output.new(asset_id, charge, addr, 0, charge_output_payload)
+ tx:appendtxout(charge_output)
+end
+
+
+print(tx:get())
+-- sign
+tx:multiprogramssigntx(wallet)
+print(tx:get())
+
+-- send
+local hash = tx:hash()
+local res = m.send_tx(tx)
+
+print("sending " .. hash)
+
+if (res ~= hash)
+ then
+ print(res)
+ else
+ print("tx send success")
+ end
diff --git a/test/transaction/register_cr_multi_tx.lua b/test/transaction/register_cr_multi_tx.lua
new file mode 100644
index 000000000..7c5e468af
--- /dev/null
+++ b/test/transaction/register_cr_multi_tx.lua
@@ -0,0 +1,114 @@
+-- Copyright (c) 2017-2020 The Elastos Foundation
+-- Use of this source code is governed by an MIT
+-- license that can be found in the LICENSE file.
+--
+
+local m = require("api")
+
+local keystore = getWallet()
+local password = getPassword()
+
+if keystore == "" then
+ keystore = "keystore.dat"
+end
+if password == "" then
+ password = "123"
+end
+
+local wallet = client.new(keystore, password, false)
+
+-- account
+local addr = wallet:get_address()
+print(addr)
+
+-- asset_id
+local asset_id = m.get_asset_id()
+
+local amount = getDepositAmount()
+local fee = getFee()
+local deposit_address = getDepositAddr()
+local nick_name = getNickName()
+local url = getUrl()
+local location = getLocation()
+local payload_version = getPayloadVersion()
+
+if amount == 0
+ then
+ amount = 5000
+end
+
+if fee == 0
+ then
+ fee = 0.1
+end
+
+if deposit_address == ""
+ then
+ print("deposit addr is nil, should use --depositaddr or -daddr to set it.")
+ return
+end
+
+if nick_name == ""
+ then
+ nick_name = "nickname_test"
+end
+
+if url == ""
+ then
+ url = "url_test"
+end
+
+if location == ""
+ then
+ location = 123
+end
+
+print("deposit amount:", amount)
+print("fee:", fee)
+print("deposit addr:", deposit_address)
+print("nick name:", nick_name)
+print("url:", url)
+print("location:", location)
+print("payload version:", payload_version)
+
+-- register cr payload: publickey, nickname, url, local, wallet
+local rp_payload =registercr.new(payload_version, nick_name, url,
+ location, 3, wallet)
+print(rp_payload:get())
+
+-- transaction: version, txType, payloadVersion, payload, locktime
+local tx = transaction.new(9, 0x21, payload_version, rp_payload, 0)
+print(tx:get())
+
+-- input: from, amount + fee
+local charge = tx:appendenough(addr, (amount + fee) * 100000000)
+print(charge)
+
+-- outputpayload
+local default_output = defaultoutput.new()
+
+-- output: asset_id, value, recipient, output_paload_type, outputpaload
+local charge_output = output.new(asset_id, charge, addr, 0, default_output)
+
+local amount_output = output.new(asset_id, amount * 100000000, deposit_address, 0, default_output)
+
+
+tx:appendtxout(charge_output)
+tx:appendtxout(amount_output)
+
+-- sign
+tx:multisign(wallet, 3)
+print(tx:get())
+
+-- send
+local hash = tx:hash()
+local res = m.send_tx(tx)
+
+print("sending " .. hash)
+
+if (res ~= hash)
+then
+ print(res)
+else
+ print("tx send success")
+end
diff --git a/test/transaction/register_cr_schnorr_tx.lua b/test/transaction/register_cr_schnorr_tx.lua
index 59285ede1..2794acb59 100644
--- a/test/transaction/register_cr_schnorr_tx.lua
+++ b/test/transaction/register_cr_schnorr_tx.lua
@@ -5,6 +5,18 @@
local m = require("api")
+local keystore = getWallet()
+local password = getPassword()
+
+if keystore == "" then
+ keystore = "keystore.dat"
+end
+if password == "" then
+ password = "123"
+end
+
+local wallet = client.new(keystore, password, false)
+
-- account
local privatekeys = getPrivateKeys()
print("------------------------")
diff --git a/test/transaction/register_producerDposV2_tx.lua b/test/transaction/register_producerDposV2_tx.lua
index b3cd50c01..11e01f2bc 100644
--- a/test/transaction/register_producerDposV2_tx.lua
+++ b/test/transaction/register_producerDposV2_tx.lua
@@ -19,9 +19,7 @@ local wallet = client.new(keystore, password, false)
-- account
local addr = wallet:get_address()
-local pubkey = wallet:get_publickey()
print(addr)
-print(pubkey)
-- asset_id
local asset_id = m.get_asset_id()
@@ -49,6 +47,7 @@ local nick_name = getNickName()
local url = getUrl()
local location = getLocation()
local host_address = getHostAddr()
+local payloadversion = getPayloadVersion()
if amount == 0
then
@@ -109,14 +108,15 @@ print("url:", url)
print("location:", location)
print("host_address",host_address)
print("stakeuntil:", stakeuntil)
+print("payloadversion:", payloadversion)
-- register producer payload: publickey, nickname, url, local, host, wallet
-local rp_payload = registerv2producer.new(own_publickey, node_publickey, nick_name, url, location, host_address, stakeuntil, wallet)
+local rp_payload = registerv2producer.new(own_publickey, node_publickey, nick_name, url, location, host_address, stakeuntil,payloadversion, wallet)
print(rp_payload:get())
-- transaction: version, txType, payloadVersion, payload, locktime
-local tx = transaction.new(9, 0x09, 1, rp_payload, 0)
+local tx = transaction.new(9, 0x09, payloadversion, rp_payload, 0)
print(tx:get())
-- input: from, amount + fee
@@ -135,7 +135,7 @@ tx:appendtxout(amount_output)
-- print(amount_output:get())
-- sign
-tx:sign(wallet)
+tx:multisign(wallet, 3)
print(tx:get())
-- send
diff --git a/test/transaction/unregister_cr_multi_tx.lua b/test/transaction/unregister_cr_multi_tx.lua
new file mode 100644
index 000000000..46325a58d
--- /dev/null
+++ b/test/transaction/unregister_cr_multi_tx.lua
@@ -0,0 +1,73 @@
+-- Copyright (c) 2017-2020 The Elastos Foundation
+-- Use of this source code is governed by an MIT
+-- license that can be found in the LICENSE file.
+--
+
+local m = require("api")
+
+local keystore = getWallet()
+local password = getPassword()
+
+if keystore == "" then
+ keystore = "keystore.dat"
+end
+if password == "" then
+ password = "123"
+end
+
+local wallet = client.new(keystore, password, false)
+
+-- account
+local addr = wallet:get_address()
+print(addr)
+
+-- asset_id
+local asset_id = m.get_asset_id()
+
+local fee = getFee()
+local payload_version = getPayloadVersion()
+
+if fee == 0
+ then
+ fee = 0.1
+end
+
+print("fee:", fee)
+print("payload version:", payload_version)
+
+-- unregister cr payload: publickey, nickname, url, local, wallet
+local ur_payload =unregistercr.newmulti(3, wallet)
+print(ur_payload:get())
+
+-- transaction: version, txType, payloadVersion, payload, locktime
+local tx = transaction.new(9, 0x22, payload_version, ur_payload, 0)
+print(tx:get())
+
+-- input: from, amount + fee
+local charge = tx:appendenough(addr, fee * 100000000)
+print(charge)
+
+-- outputpayload
+local default_output = defaultoutput.new()
+
+-- output: asset_id, value, recipient, output_paload_type, outputpaload
+local charge_output = output.new(asset_id, charge, addr, 0, default_output)
+
+tx:appendtxout(charge_output)
+
+-- sign
+tx:multisign(wallet, 3)
+print(tx:get())
+
+-- send
+local hash = tx:hash()
+local res = m.send_tx(tx)
+
+print("sending " .. hash)
+
+if (res ~= hash)
+then
+ print(res)
+else
+ print("tx send success")
+end
diff --git a/test/transaction/update_cr_multi_tx.lua b/test/transaction/update_cr_multi_tx.lua
new file mode 100644
index 000000000..9d81c8b3e
--- /dev/null
+++ b/test/transaction/update_cr_multi_tx.lua
@@ -0,0 +1,95 @@
+-- Copyright (c) 2017-2020 The Elastos Foundation
+-- Use of this source code is governed by an MIT
+-- license that can be found in the LICENSE file.
+--
+
+local m = require("api")
+
+local keystore = getWallet()
+local password = getPassword()
+
+if keystore == "" then
+ keystore = "keystore.dat"
+end
+if password == "" then
+ password = "123"
+end
+
+local wallet = client.new(keystore, password, false)
+
+-- account
+local addr = wallet:get_address()
+print(addr)
+
+-- asset_id
+local asset_id = m.get_asset_id()
+
+local fee = getFee()
+local nick_name = getNickName()
+local url = getUrl()
+local location = getLocation()
+local payload_version = getPayloadVersion()
+
+if fee == 0
+ then
+ fee = 0.1
+end
+
+if nick_name == ""
+ then
+ nick_name = "nickname_test"
+end
+
+if url == ""
+ then
+ url = "url_test"
+end
+
+if location == ""
+ then
+ location = 123
+end
+
+print("fee:", fee)
+print("nick name:", nick_name)
+print("url:", url)
+print("location:", location)
+print("payload version:", payload_version)
+
+-- update cr payload: publickey, nickname, url, local, wallet
+local up_payload =updatecr.new(payload_version, nick_name, url,
+ location, 3, wallet)
+print(up_payload:get())
+
+-- transaction: version, txType, payloadVersion, payload, locktime
+local tx = transaction.new(9, 0x23, payload_version, up_payload, 0)
+print(tx:get())
+
+-- input: from, amount + fee
+local charge = tx:appendenough(addr, fee * 100000000)
+print(charge)
+
+-- outputpayload
+local default_output = defaultoutput.new()
+
+-- output: asset_id, value, recipient, output_paload_type, outputpaload
+local charge_output = output.new(asset_id, charge, addr, 0, default_output)
+
+tx:appendtxout(charge_output)
+
+-- sign
+tx:multisign(wallet, 3)
+print(tx:get())
+
+-- send
+local hash = tx:hash()
+local res = m.send_tx(tx)
+
+print("sending " .. hash)
+
+if (res ~= hash)
+then
+ print(res)
+else
+ print("tx send success")
+end
diff --git a/test/transaction/update_cr_schnorr_tx.lua b/test/transaction/update_cr_schnorr_tx.lua
index 837cc7983..583f9a463 100644
--- a/test/transaction/update_cr_schnorr_tx.lua
+++ b/test/transaction/update_cr_schnorr_tx.lua
@@ -5,6 +5,18 @@
local m = require("api")
+local keystore = getWallet()
+local password = getPassword()
+
+if keystore == "" then
+ keystore = "keystore.dat"
+end
+if password == "" then
+ password = "123"
+end
+
+local wallet = client.new(keystore, password, false)
+
-- account
local privatekeys = getPrivateKeys()
print("------------------------")
@@ -87,8 +99,8 @@ print("location:", location)
print("payload version:", payload_version)
-- register cr payload: publickey, nickname, url, local, wallet
-local up_payload =updatecr.new(cr_publickey, nick_name, url, location,
- payload_version, wallet)
+local up_payload =updatecr.new(payload_version, cr_publickey, nick_name, url,
+ location, wallet)
print(up_payload:get())
-- transaction: version, txType, payloadVersion, payload, locktime
diff --git a/test/transaction/update_cr_tx.lua b/test/transaction/update_cr_tx.lua
index a91abb1f0..0b0c41ab1 100644
--- a/test/transaction/update_cr_tx.lua
+++ b/test/transaction/update_cr_tx.lua
@@ -76,8 +76,8 @@ print("location:", location)
print("payload version:", payload_version)
-- register cr payload: publickey, nickname, url, local, wallet
-local up_payload =updatecr.new(cr_publickey, nick_name, url, location,
- payload_version, wallet)
+local up_payload =updatecr.new(payload_version, cr_publickey, nick_name, url,
+ location, wallet)
print(up_payload:get())
-- transaction: version, txType, payloadVersion, payload, locktime
diff --git a/test/transaction/update_producer_v2_tx.lua b/test/transaction/update_producer_v2_tx.lua
index 771ee246c..3096fb833 100644
--- a/test/transaction/update_producer_v2_tx.lua
+++ b/test/transaction/update_producer_v2_tx.lua
@@ -19,9 +19,7 @@ local wallet = client.new(keystore, password, false)
-- account
local addr = wallet:get_address()
-local pubkey = wallet:get_publickey()
print(addr)
-print(pubkey)
-- asset_id
local asset_id = m.get_asset_id()
@@ -44,6 +42,7 @@ local nick_name = getNickName()
local url = getUrl()
local location = getLocation()
local host_address = getHostAddr()
+local payloadversion = getPayloadVersion()
if stakeuntil == ""
then
@@ -91,13 +90,14 @@ print("url:", url)
print("location:", location)
print("host address:", host_address)
print("stakeuntil:", stakeuntil)
+print("payloadversion:", payloadversion)
-- update producer payload: publickey, nickname, url, local, host, wallet
-local up_payload = updateproducer.new(own_publickey, node_publickey, nick_name, url, location, host_address, stakeuntil, wallet)
+local up_payload = updateproducer.new(own_publickey, node_publickey, nick_name, url, location, host_address, stakeuntil,payloadversion, wallet)
print(up_payload:get())
-- transaction: version, txType, payloadVersion, payload, locktime
-local tx = transaction.new(9, 0x0b, 1, up_payload, 0)
+local tx = transaction.new(9, 0x0b, payloadversion, up_payload, 0)
-- input: from, amount + fee
local charge = tx:appendenough(addr, fee * 100000000)
@@ -112,7 +112,8 @@ tx:appendtxout(charge_output)
-- print(charge_output:get())
-- sign
-tx:sign(wallet)
+--tx:sign(wallet)
+tx:multisign(wallet, 3)
print(tx:get())
-- send
diff --git a/test/unit/arbitratorsrollback_test.go b/test/unit/arbitratorsrollback_test.go
index b6780b994..c345a1c19 100644
--- a/test/unit/arbitratorsrollback_test.go
+++ b/test/unit/arbitratorsrollback_test.go
@@ -147,9 +147,9 @@ func getRegisterProducerTx(ownerPublicKey, nodePublicKey []byte,
common2.RegisterProducer,
0,
&payload.ProducerInfo{
- OwnerPublicKey: ownerPublicKey,
- NodePublicKey: nodePublicKey,
- NickName: nickName,
+ OwnerKey: ownerPublicKey,
+ NodePublicKey: nodePublicKey,
+ NickName: nickName,
},
[]*common2.Attribute{},
[]*common2.Input{},
@@ -206,9 +206,9 @@ func getUpdateProducerTx(ownerPublicKey, nodePublicKey []byte,
common2.UpdateProducer,
0,
&payload.ProducerInfo{
- OwnerPublicKey: ownerPublicKey,
- NodePublicKey: nodePublicKey,
- NickName: nickName,
+ OwnerKey: ownerPublicKey,
+ NodePublicKey: nodePublicKey,
+ NickName: nickName,
},
[]*common2.Attribute{},
[]*common2.Input{},
@@ -226,7 +226,7 @@ func getCancelProducer(publicKey []byte) interfaces.Transaction {
common2.CancelProducer,
0,
&payload.ProcessProducer{
- OwnerPublicKey: publicKey,
+ OwnerKey: publicKey,
},
[]*common2.Attribute{},
[]*common2.Input{},
@@ -572,7 +572,7 @@ func TestArbitrators_RollbackReturnProducerDeposit(t *testing.T) {
producers := abt.GetAllProducers()
for _, v := range producers {
hash, _ := contract.PublicKeyToDepositProgramHash(
- v.Info().OwnerPublicKey)
+ v.Info().OwnerKey)
if hash.IsEqual(programHash) {
return v.DepositAmount(), nil
}
@@ -983,7 +983,7 @@ func TestArbitrators_RollbackMultipleTransactions(t *testing.T) {
producers := abt.GetAllProducers()
for _, v := range producers {
hash, _ := contract.PublicKeyToDepositProgramHash(
- v.Info().OwnerPublicKey)
+ v.Info().OwnerKey)
if hash.IsEqual(programHash) {
return v.DepositAmount(), nil
}
diff --git a/test/unit/blockvalidator_test.go b/test/unit/blockvalidator_test.go
index 35657140d..be921e990 100644
--- a/test/unit/blockvalidator_test.go
+++ b/test/unit/blockvalidator_test.go
@@ -451,12 +451,12 @@ func generateRegisterProducer() interfaces.Transaction {
common2.RegisterProducer,
0,
&payload.ProducerInfo{
- OwnerPublicKey: publicKey1,
- NodePublicKey: publicKey1,
- NickName: "nickname 1",
- Url: "http://www.elastos_test.com",
- Location: 1,
- NetAddress: "127.0.0.1:20338",
+ OwnerKey: publicKey1,
+ NodePublicKey: publicKey1,
+ NickName: "nickname 1",
+ Url: "http://www.elastos_test.com",
+ Location: 1,
+ NetAddress: "127.0.0.1:20338",
},
[]*common2.Attribute{},
[]*common2.Input{},
@@ -475,12 +475,12 @@ func generateUpdateProducer() interfaces.Transaction {
common2.UpdateProducer,
0,
&payload.ProducerInfo{
- OwnerPublicKey: publicKey1,
- NodePublicKey: publicKey1,
- NickName: "nickname 1",
- Url: "http://www.elastos_test.com",
- Location: 1,
- NetAddress: "127.0.0.1:20338",
+ OwnerKey: publicKey1,
+ NodePublicKey: publicKey1,
+ NickName: "nickname 1",
+ Url: "http://www.elastos_test.com",
+ Location: 1,
+ NetAddress: "127.0.0.1:20338",
},
[]*common2.Attribute{},
[]*common2.Input{},
@@ -499,7 +499,7 @@ func generateCancelProducer() interfaces.Transaction {
common2.CancelProducer,
0,
&payload.ProcessProducer{
- OwnerPublicKey: publicKey1,
+ OwnerKey: publicKey1,
},
[]*common2.Attribute{},
[]*common2.Input{},
diff --git a/test/unit/committeerollback_test.go b/test/unit/committeerollback_test.go
index fd1c48507..c5eba10d7 100644
--- a/test/unit/committeerollback_test.go
+++ b/test/unit/committeerollback_test.go
@@ -212,7 +212,7 @@ func getCRCProposalTx(elaAddress string, publicKeyStr, privateKeyStr,
crcProposalPayload := &payload.CRCProposal{
ProposalType: payload.Normal,
- OwnerPublicKey: publicKey1,
+ OwnerKey: publicKey1,
CRCouncilMemberDID: *getDID(code2),
DraftHash: common.Hash(draftData),
Budgets: createBudgets(3),
@@ -309,8 +309,8 @@ func getCRCProposalTrackingTx(
ProposalHash: proposalHash,
Stage: stage,
MessageHash: common.Hash(documentData),
- OwnerPublicKey: ownerpublickey,
- NewOwnerPublicKey: newownerpublickey,
+ OwnerKey: ownerpublickey,
+ NewOwnerKey: newownerpublickey,
SecretaryGeneralOpinionHash: common.Hash(opinionHash),
}
@@ -354,8 +354,8 @@ func getCRCProposalWithdrawTx(proposalHash common.Uint256,
sponsorPrivateKey, _ := common.HexStringToBytes(sponsorPrivateKeyStr)
crcProposalWithdraw := &payload.CRCProposalWithdraw{
- ProposalHash: proposalHash,
- OwnerPublicKey: OwnerPublicKey,
+ ProposalHash: proposalHash,
+ OwnerKey: OwnerPublicKey,
}
signBuf := new(bytes.Buffer)
diff --git a/test/unit/crkeyframe_test.go b/test/unit/crkeyframe_test.go
index e66b7b046..49f857611 100644
--- a/test/unit/crkeyframe_test.go
+++ b/test/unit/crkeyframe_test.go
@@ -598,7 +598,7 @@ func randomProposalHashSet() state.ProposalHashSet {
func randomCRCProposal() *payload.CRCProposal {
return &payload.CRCProposal{
ProposalType: payload.CRCProposalType(rand.Int31n(6)),
- OwnerPublicKey: randomBytes(33),
+ OwnerKey: randomBytes(33),
CRCouncilMemberDID: *randomUint168(),
DraftHash: *randomUint256(),
Budgets: createBudgets(5),
diff --git a/test/unit/dposkeyframe_test.go b/test/unit/dposkeyframe_test.go
index c0d80d464..de5f7b2c6 100644
--- a/test/unit/dposkeyframe_test.go
+++ b/test/unit/dposkeyframe_test.go
@@ -74,7 +74,8 @@ func dposCheckPointsEqual(first *state.CheckPoint, second *state.CheckPoint) boo
second.CurrentReward.TotalVotesInRound ||
second.NextReward.TotalVotesInRound !=
second.NextReward.TotalVotesInRound ||
- first.ForceChanged != second.ForceChanged {
+ first.ForceChanged != second.ForceChanged ||
+ first.NeedNextTurnDPOSInfo != second.NeedNextTurnDPOSInfo {
return false
}
@@ -366,6 +367,7 @@ func randomDPOSStateKeyFrame() *state.StateKeyFrame {
VersionStartHeight: rand.Uint32(),
VersionEndHeight: rand.Uint32(),
DPoSV2ActiveHeight: rand.Uint32(),
+ NeedNextTurnDPOSInfo: randomBool(),
}
for i := 0; i < 5; i++ {
@@ -426,7 +428,7 @@ func producerInfoEqual(first *payload.ProducerInfo,
return false
}
- return bytes.Equal(first.OwnerPublicKey, second.OwnerPublicKey) &&
+ return bytes.Equal(first.OwnerKey, second.OwnerKey) &&
bytes.Equal(first.NodePublicKey, second.NodePublicKey) &&
bytes.Equal(first.Signature, second.Signature)
}
@@ -488,13 +490,13 @@ func randomProgramHash() *common.Uint168 {
func randomProducer() *state.Producer {
p := &state.Producer{}
p.SetInfo(payload.ProducerInfo{
- OwnerPublicKey: randomFakePK(),
- NodePublicKey: randomFakePK(),
- NickName: randomString(),
- Url: randomString(),
- Location: rand.Uint64(),
- NetAddress: randomString(),
- Signature: randomBytes(64),
+ OwnerKey: randomFakePK(),
+ NodePublicKey: randomFakePK(),
+ NickName: randomString(),
+ Url: randomString(),
+ Location: rand.Uint64(),
+ NetAddress: randomString(),
+ Signature: randomBytes(64),
})
p.SetState(state.ProducerState(rand.Uint32()))
p.SetRegisterHeight(rand.Uint32())
diff --git a/test/unit/dposstate_test.go b/test/unit/dposstate_test.go
index 7436812d6..ada3fc634 100644
--- a/test/unit/dposstate_test.go
+++ b/test/unit/dposstate_test.go
@@ -89,7 +89,7 @@ func mockCancelProducerTx(publicKey []byte) interfaces.Transaction {
common2.CancelProducer,
0,
&payload.ProcessProducer{
- OwnerPublicKey: publicKey,
+ OwnerKey: publicKey,
},
[]*common2.Attribute{},
[]*common2.Input{},
@@ -263,8 +263,8 @@ func TestState_ProcessTransaction(t *testing.T) {
producers := make([]*payload.ProducerInfo, 10)
for i, p := range producers {
p = &payload.ProducerInfo{
- OwnerPublicKey: randomPublicKey(),
- NodePublicKey: make([]byte, 33),
+ OwnerKey: randomPublicKey(),
+ NodePublicKey: make([]byte, 33),
}
rand.Read(p.NodePublicKey)
p.NickName = fmt.Sprintf("Producer-%d", i+1)
@@ -304,7 +304,7 @@ func TestState_ProcessTransaction(t *testing.T) {
}
// Test cancel producer.
- tx = mockCancelProducerTx(producers[0].OwnerPublicKey)
+ tx = mockCancelProducerTx(producers[0].OwnerKey)
state.ProcessBlock(mockBlock(12, tx), nil, 0)
// at this point, we have 1 canceled, 3 pending, 6 active and 9 in total producers.
if !assert.Equal(t, 1, len(state.GetCanceledProducers())) {
@@ -323,14 +323,14 @@ func TestState_ProcessTransaction(t *testing.T) {
// Test vote producer.
publicKeys := make([][]byte, 5)
for i, p := range producers[0:5] {
- publicKeys[i] = p.OwnerPublicKey
+ publicKeys[i] = p.OwnerKey
}
tx = mockVoteTx(publicKeys)
// Test new version vote producer.
publicKeys2 := make([][]byte, 5)
for i, p := range producers[5:10] {
- publicKeys2[i] = p.OwnerPublicKey
+ publicKeys2[i] = p.OwnerKey
}
tx2 := mockNewDPoSVoteTx(publicKeys2)
@@ -381,8 +381,8 @@ func TestState_ProcessBlock(t *testing.T) {
producers := make([]*payload.ProducerInfo, 100)
for i, p := range producers {
p = &payload.ProducerInfo{
- OwnerPublicKey: randomPublicKey(),
- NodePublicKey: make([]byte, 33),
+ OwnerKey: randomPublicKey(),
+ NodePublicKey: make([]byte, 33),
}
rand.Read(p.NodePublicKey)
p.NickName = fmt.Sprintf("Producer-%d", i+1)
@@ -425,7 +425,7 @@ func TestState_ProcessBlock(t *testing.T) {
// Cancel 10 producers.
txs = make([]interfaces.Transaction, 10)
for i := range txs {
- txs[i] = mockCancelProducerTx(producers[i].OwnerPublicKey)
+ txs[i] = mockCancelProducerTx(producers[i].OwnerKey)
}
state.ProcessBlock(mockBlock(12, txs...), nil, 0)
// at this point, we have 10 canceled, 30 pending, 60 active and 90 in total producers.
@@ -445,7 +445,7 @@ func TestState_ProcessBlock(t *testing.T) {
// Vote 10 producers for 10 times.
publicKeys := make([][]byte, 10)
for i, p := range producers[10:20] {
- publicKeys[i] = p.OwnerPublicKey
+ publicKeys[i] = p.OwnerKey
}
txs = make([]interfaces.Transaction, 10)
for i := range txs {
@@ -485,15 +485,15 @@ func TestState_ProcessBlock(t *testing.T) {
// Mixed transactions 1 register, 2 cancel, 3 updates, 4 votes, 5 illegals.
txs = make([]interfaces.Transaction, 15)
info := &payload.ProducerInfo{
- OwnerPublicKey: randomPublicKey(),
- NodePublicKey: make([]byte, 33),
+ OwnerKey: randomPublicKey(),
+ NodePublicKey: make([]byte, 33),
}
rand.Read(info.NodePublicKey)
info.NickName = "Producer-101"
txs[0] = mockRegisterProducerTx(info)
for i := 0; i < 2; i++ {
- txs[1+i] = mockCancelProducerTx(producers[20+i].OwnerPublicKey)
+ txs[1+i] = mockCancelProducerTx(producers[20+i].OwnerKey)
}
for i := 0; i < 3; i++ {
@@ -502,7 +502,7 @@ func TestState_ProcessBlock(t *testing.T) {
publicKeys = make([][]byte, 4)
for i, p := range producers[40:44] {
- publicKeys[i] = p.OwnerPublicKey
+ publicKeys[i] = p.OwnerKey
}
for i := 0; i < 4; i++ {
txs[6+i] = mockVoteTx(publicKeys)
@@ -551,8 +551,8 @@ func TestState_ProcessIllegalBlockEvidence(t *testing.T) {
producers := make([]*payload.ProducerInfo, 10)
for i, p := range producers {
p = &payload.ProducerInfo{
- OwnerPublicKey: randomPublicKey(),
- NodePublicKey: make([]byte, 33),
+ OwnerKey: randomPublicKey(),
+ NodePublicKey: make([]byte, 33),
}
rand.Read(p.NodePublicKey)
p.NickName = fmt.Sprintf("Producer-%d", i+1)
@@ -607,8 +607,8 @@ func TestState_ProcessEmergencyInactiveArbitrators(t *testing.T) {
producers := make([]*payload.ProducerInfo, 10)
for i, p := range producers {
p = &payload.ProducerInfo{
- OwnerPublicKey: randomPublicKey(),
- NodePublicKey: make([]byte, 33),
+ OwnerKey: randomPublicKey(),
+ NodePublicKey: make([]byte, 33),
}
rand.Read(p.NodePublicKey)
p.NickName = fmt.Sprintf("Producer-%d", i+1)
@@ -666,8 +666,8 @@ func TestState_Rollback(t *testing.T) {
producers := make([]*payload.ProducerInfo, 10)
for i, p := range producers {
p = &payload.ProducerInfo{
- OwnerPublicKey: randomPublicKey(),
- NodePublicKey: make([]byte, 33),
+ OwnerKey: randomPublicKey(),
+ NodePublicKey: make([]byte, 33),
}
rand.Read(p.NodePublicKey)
p.NickName = fmt.Sprintf("Producer-%d", i+1)
@@ -717,8 +717,8 @@ func TestState_GetHistory(t *testing.T) {
producers := make([]*payload.ProducerInfo, 10)
for i, p := range producers {
p = &payload.ProducerInfo{
- OwnerPublicKey: randomPublicKey(),
- NodePublicKey: make([]byte, 33),
+ OwnerKey: randomPublicKey(),
+ NodePublicKey: make([]byte, 33),
}
rand.Read(p.NodePublicKey)
p.NickName = fmt.Sprintf("Producer-%d", i+1)
@@ -748,14 +748,14 @@ func TestState_GetHistory(t *testing.T) {
}
// Test cancel producer.
- tx = mockCancelProducerTx(producers[0].OwnerPublicKey)
+ tx = mockCancelProducerTx(producers[0].OwnerKey)
state.ProcessBlock(mockBlock(12, tx), nil, 0)
// At this point, we have 1 canceled, 3 pending, 6 active and 9 in total producers.
// Test vote producer.
publicKeys := make([][]byte, 5)
for i, p := range producers[1:6] {
- publicKeys[i] = p.OwnerPublicKey
+ publicKeys[i] = p.OwnerKey
}
tx = mockVoteTx(publicKeys)
state.ProcessBlock(mockBlock(13, tx), nil, 0)
@@ -866,8 +866,8 @@ func TestState_NicknameExists(t *testing.T) {
producers := make([]*payload.ProducerInfo, 10)
for i, p := range producers {
p = &payload.ProducerInfo{
- OwnerPublicKey: randomPublicKey(),
- NodePublicKey: make([]byte, 33),
+ OwnerKey: randomPublicKey(),
+ NodePublicKey: make([]byte, 33),
}
rand.Read(p.NodePublicKey)
p.NickName = fmt.Sprintf("Producer-%d", i+1)
@@ -907,7 +907,7 @@ func TestState_NicknameExists(t *testing.T) {
}
// Cancel producer-2, see if nickname change to unused.
- tx = mockCancelProducerTx(producers[1].OwnerPublicKey)
+ tx = mockCancelProducerTx(producers[1].OwnerKey)
state.ProcessBlock(mockBlock(12, tx), nil, 0)
if !assert.Equal(t, false, state.NicknameExists("Producer-2")) {
t.FailNow()
@@ -932,8 +932,8 @@ func TestState_ProducerExists(t *testing.T) {
producers := make([]*payload.ProducerInfo, 10)
for i, p := range producers {
p = &payload.ProducerInfo{
- OwnerPublicKey: randomPublicKey(),
- NodePublicKey: make([]byte, 33),
+ OwnerKey: randomPublicKey(),
+ NodePublicKey: make([]byte, 33),
}
rand.Read(p.NodePublicKey)
p.NickName = fmt.Sprintf("Producer-%d", i+1)
@@ -950,7 +950,7 @@ func TestState_ProducerExists(t *testing.T) {
if !assert.Equal(t, true, state.ProducerExists(p.NodePublicKey)) {
t.FailNow()
}
- if !assert.Equal(t, true, state.ProducerExists(p.OwnerPublicKey)) {
+ if !assert.Equal(t, true, state.ProducerExists(p.OwnerKey)) {
t.FailNow()
}
}
@@ -969,9 +969,9 @@ func TestState_ProducerExists(t *testing.T) {
}
// Canceled producer also existed.
- tx = mockCancelProducerTx(producers[0].OwnerPublicKey)
+ tx = mockCancelProducerTx(producers[0].OwnerKey)
state.ProcessBlock(mockBlock(12, tx), nil, 0)
- if !assert.Equal(t, true, state.ProducerExists(producers[0].OwnerPublicKey)) {
+ if !assert.Equal(t, true, state.ProducerExists(producers[0].OwnerKey)) {
t.FailNow()
}
}
@@ -988,9 +988,9 @@ func TestState_IsDPOSTransaction(t *testing.T) {
}
producer := &payload.ProducerInfo{
- OwnerPublicKey: randomPublicKey(),
- NodePublicKey: make([]byte, 33),
- NickName: "Producer",
+ OwnerKey: randomPublicKey(),
+ NodePublicKey: make([]byte, 33),
+ NickName: "Producer",
}
rand.Read(producer.NodePublicKey)
@@ -1008,12 +1008,12 @@ func TestState_IsDPOSTransaction(t *testing.T) {
t.FailNow()
}
- tx = mockCancelProducerTx(producer.OwnerPublicKey)
+ tx = mockCancelProducerTx(producer.OwnerKey)
if !assert.Equal(t, true, state.IsDPOSTransaction(tx)) {
t.FailNow()
}
- tx = mockVoteTx([][]byte{producer.OwnerPublicKey})
+ tx = mockVoteTx([][]byte{producer.OwnerKey})
if !assert.Equal(t, true, state.IsDPOSTransaction(tx)) {
t.FailNow()
}
@@ -1030,12 +1030,12 @@ func TestState_IsDPOSTransaction(t *testing.T) {
references[input] = *tx.Outputs()[i]
}
state.ProcessBlock(mockBlock(11, tx2), nil, 0)
- p = state.GetProducer(producer.OwnerPublicKey)
+ p = state.GetProducer(producer.OwnerKey)
if !assert.Equal(t, common.Fixed64(0), p.Votes()) {
t.FailNow()
}
- tx2 = mockIllegalBlockTx(producer.OwnerPublicKey)
+ tx2 = mockIllegalBlockTx(producer.OwnerKey)
if !assert.Equal(t, true, state.IsDPOSTransaction(tx2)) {
t.FailNow()
}
@@ -1054,8 +1054,8 @@ func TestState_InactiveProducer_Normal(t *testing.T) {
producers := make([]*payload.ProducerInfo, 10)
for i, p := range producers {
p = &payload.ProducerInfo{
- OwnerPublicKey: randomPublicKey(),
- NodePublicKey: randomPublicKey(),
+ OwnerKey: randomPublicKey(),
+ NodePublicKey: randomPublicKey(),
}
p.NickName = fmt.Sprintf("Producer-%d", i+1)
producers[i] = p
@@ -1126,8 +1126,8 @@ func TestState_InactiveProducer_FailNoContinuous(t *testing.T) {
producers := make([]*payload.ProducerInfo, 10)
for i, p := range producers {
p = &payload.ProducerInfo{
- OwnerPublicKey: randomPublicKey(),
- NodePublicKey: randomPublicKey(),
+ OwnerKey: randomPublicKey(),
+ NodePublicKey: randomPublicKey(),
}
p.NickName = fmt.Sprintf("Producer-%d", i+1)
producers[i] = p
@@ -1198,8 +1198,8 @@ func TestState_InactiveProducer_RecoverFromInactiveState(t *testing.T) {
producers := make([]*payload.ProducerInfo, 10)
for i, p := range producers {
p = &payload.ProducerInfo{
- OwnerPublicKey: randomPublicKey(),
- NodePublicKey: randomPublicKey(),
+ OwnerKey: randomPublicKey(),
+ NodePublicKey: randomPublicKey(),
}
p.NickName = fmt.Sprintf("Producer-%d", i+1)
producers[i] = p
@@ -1260,7 +1260,7 @@ func TestState_InactiveProducer_RecoverFromInactiveState(t *testing.T) {
// request for activating
state.ProcessBlock(mockBlock(uint32(currentHeight),
- mockActivateProducerTx(producers[0].OwnerPublicKey)), nil, 0)
+ mockActivateProducerTx(producers[0].OwnerKey)), nil, 0)
currentHeight++
// producer[0] will not be active util 6 blocks later
@@ -1289,8 +1289,8 @@ func TestState_InactiveProducer_DuringUpdateVersion(t *testing.T) {
producers := make([]*payload.ProducerInfo, 10)
for i, p := range producers {
p = &payload.ProducerInfo{
- OwnerPublicKey: randomPublicKey(),
- NodePublicKey: randomPublicKey(),
+ OwnerKey: randomPublicKey(),
+ NodePublicKey: randomPublicKey(),
}
p.NickName = fmt.Sprintf("Producer-%d", i+1)
producers[i] = p
@@ -1387,9 +1387,9 @@ func TestDPoSState_ProcessBlock_DepositAndReturnDeposit(t *testing.T) {
common2.RegisterProducer,
0,
&payload.ProducerInfo{
- OwnerPublicKey: pkBuf,
- NodePublicKey: pkBuf,
- NickName: randomString(),
+ OwnerKey: pkBuf,
+ NodePublicKey: pkBuf,
+ NickName: randomString(),
},
[]*common2.Attribute{},
[]*common2.Input{},
@@ -1472,7 +1472,7 @@ func TestDPoSState_ProcessBlock_DepositAndReturnDeposit(t *testing.T) {
common2.CancelProducer,
0,
&payload.ProcessProducer{
- OwnerPublicKey: pkBuf,
+ OwnerKey: pkBuf,
},
[]*common2.Attribute{},
[]*common2.Input{},
@@ -1539,8 +1539,8 @@ func TestState_CountArbitratorsInactivityV1(t *testing.T) {
producers := make([]*payload.ProducerInfo, 100)
for i, p := range producers {
p = &payload.ProducerInfo{
- OwnerPublicKey: randomPublicKey(),
- NodePublicKey: make([]byte, 33),
+ OwnerKey: randomPublicKey(),
+ NodePublicKey: make([]byte, 33),
}
rand.Read(p.NodePublicKey)
p.NickName = fmt.Sprintf("Producer-%d", i+1)
@@ -1583,7 +1583,7 @@ func TestState_CountArbitratorsInactivityV1(t *testing.T) {
// Cancel 10 producers.
txs = make([]interfaces.Transaction, 10)
for i := range txs {
- txs[i] = mockCancelProducerTx(producers[i].OwnerPublicKey)
+ txs[i] = mockCancelProducerTx(producers[i].OwnerKey)
}
state.ProcessBlock(mockBlock(12, txs...), nil, 0)
// at this point, we have 10 canceled, 30 pending, 60 active and 90 in total producers.
@@ -1603,7 +1603,7 @@ func TestState_CountArbitratorsInactivityV1(t *testing.T) {
// Vote 10 producers for 10 times.
publicKeys := make([][]byte, 10)
for i, p := range producers[10:20] {
- publicKeys[i] = p.OwnerPublicKey
+ publicKeys[i] = p.OwnerKey
}
txs = make([]interfaces.Transaction, 10)
for i := range txs {
diff --git a/test/unit/heightversion_test.go b/test/unit/heightversion_test.go
index 1adeeefe9..db8dab81a 100644
--- a/test/unit/heightversion_test.go
+++ b/test/unit/heightversion_test.go
@@ -101,8 +101,8 @@ func TestArbitrators_GetNormalArbitratorsDesc(t *testing.T) {
common2.RegisterProducer,
0,
&payload.ProducerInfo{
- OwnerPublicKey: arbitratorList[i],
- NodePublicKey: arbitratorList[i],
+ OwnerKey: arbitratorList[i],
+ NodePublicKey: arbitratorList[i],
},
[]*common2.Attribute{},
[]*common2.Input{},
@@ -143,8 +143,8 @@ func TestArbitrators_GetNormalArbitratorsDesc(t *testing.T) {
common2.RegisterProducer,
0,
&payload.ProducerInfo{
- OwnerPublicKey: arbitratorList[4],
- NodePublicKey: arbitratorList[4],
+ OwnerKey: arbitratorList[4],
+ NodePublicKey: arbitratorList[4],
},
[]*common2.Attribute{},
[]*common2.Input{},
diff --git a/test/unit/reward_test.go b/test/unit/reward_test.go
index 015dcb54c..06294823b 100644
--- a/test/unit/reward_test.go
+++ b/test/unit/reward_test.go
@@ -123,8 +123,8 @@ func TestCommittee_ChangeCommitteeReward(t *testing.T) {
producers := make([]*payload.ProducerInfo, 200)
for i, p := range producers {
p = &payload.ProducerInfo{
- OwnerPublicKey: randomPublicKey(),
- NodePublicKey: make([]byte, 33),
+ OwnerKey: randomPublicKey(),
+ NodePublicKey: make([]byte, 33),
}
rand.Read(p.NodePublicKey)
p.NickName = fmt.Sprintf("Producer-%d", i+1)
@@ -153,7 +153,7 @@ func TestCommittee_ChangeCommitteeReward(t *testing.T) {
// Vote 140 producers.
publicKeys := make([][]byte, 140)
for i, p := range producers[10:150] {
- publicKeys[i] = p.OwnerPublicKey
+ publicKeys[i] = p.OwnerKey
}
voteTX := mockVoteTx(publicKeys)
arbitrators.ProcessBlock(mockBlock(23, voteTX), nil)
diff --git a/test/unit/transaction_test.go b/test/unit/transaction_test.go
index 07f21687e..fa09f87d0 100644
--- a/test/unit/transaction_test.go
+++ b/test/unit/transaction_test.go
@@ -261,11 +261,11 @@ func (s *transactionSuite) TestTransferCrossChainAsset_SerializeDeserialize() {
func (s *transactionSuite) TestRegisterProducer_SerializeDeserialize() {
txn := randomOldVersionTransaction(false, byte(common2.RegisterProducer), s.InputNum, s.OutputNum, s.AttrNum, s.ProgramNum)
txn.SetPayload(&payload.ProducerInfo{
- OwnerPublicKey: []byte(strconv.FormatUint(rand.Uint64(), 10)),
- NickName: strconv.FormatUint(rand.Uint64(), 10),
- Url: strconv.FormatUint(rand.Uint64(), 10),
- Location: rand.Uint64(),
- NetAddress: strconv.FormatUint(rand.Uint64(), 10),
+ OwnerKey: []byte(strconv.FormatUint(rand.Uint64(), 10)),
+ NickName: strconv.FormatUint(rand.Uint64(), 10),
+ Url: strconv.FormatUint(rand.Uint64(), 10),
+ Location: rand.Uint64(),
+ NetAddress: strconv.FormatUint(rand.Uint64(), 10),
})
serializedData := new(bytes.Buffer)
@@ -283,7 +283,7 @@ func (s *transactionSuite) TestRegisterProducer_SerializeDeserialize() {
p1 := txn.Payload().(*payload.ProducerInfo)
p2 := txn2.Payload().(*payload.ProducerInfo)
- s.True(bytes.Equal(p1.OwnerPublicKey, p2.OwnerPublicKey))
+ s.True(bytes.Equal(p1.OwnerKey, p2.OwnerKey))
s.Equal(p1.NickName, p2.NickName)
s.Equal(p1.Url, p2.Url)
s.Equal(p1.Location, p2.Location)
@@ -294,8 +294,8 @@ func (s *transactionSuite) TestCancelProducer_SerializeDeserialize() {
txn := randomOldVersionTransaction(false, byte(common2.CancelProducer),
s.InputNum, s.OutputNum, s.AttrNum, s.ProgramNum)
txn.SetPayload(&payload.ProcessProducer{
- OwnerPublicKey: []byte(strconv.FormatUint(rand.Uint64(), 10)),
- Signature: randomSignature(),
+ OwnerKey: []byte(strconv.FormatUint(rand.Uint64(), 10)),
+ Signature: randomSignature(),
})
serializedData := new(bytes.Buffer)
@@ -314,7 +314,7 @@ func (s *transactionSuite) TestCancelProducer_SerializeDeserialize() {
p1 := txn.Payload().(*payload.ProcessProducer)
p2 := txn2.Payload().(*payload.ProcessProducer)
- s.True(bytes.Equal(p1.OwnerPublicKey, p2.OwnerPublicKey))
+ s.True(bytes.Equal(p1.OwnerKey, p2.OwnerKey))
s.True(bytes.Equal(p1.Signature, p2.Signature))
}
@@ -349,11 +349,11 @@ func (s *transactionSuite) TestActivateProducer_SerializeDeserialize() {
func (s *transactionSuite) TestUpdateProducer_SerializeDeserialize() {
txn := randomOldVersionTransaction(false, byte(common2.UpdateProducer), s.InputNum, s.OutputNum, s.AttrNum, s.ProgramNum)
txn.SetPayload(&payload.ProducerInfo{
- OwnerPublicKey: []byte(strconv.FormatUint(rand.Uint64(), 10)),
- NickName: strconv.FormatUint(rand.Uint64(), 10),
- Url: strconv.FormatUint(rand.Uint64(), 10),
- Location: rand.Uint64(),
- NetAddress: strconv.FormatUint(rand.Uint64(), 10),
+ OwnerKey: []byte(strconv.FormatUint(rand.Uint64(), 10)),
+ NickName: strconv.FormatUint(rand.Uint64(), 10),
+ Url: strconv.FormatUint(rand.Uint64(), 10),
+ Location: rand.Uint64(),
+ NetAddress: strconv.FormatUint(rand.Uint64(), 10),
})
serializedData := new(bytes.Buffer)
@@ -371,7 +371,7 @@ func (s *transactionSuite) TestUpdateProducer_SerializeDeserialize() {
p1 := txn.Payload().(*payload.ProducerInfo)
p2 := txn2.Payload().(*payload.ProducerInfo)
- s.True(bytes.Equal(p1.OwnerPublicKey, p2.OwnerPublicKey))
+ s.True(bytes.Equal(p1.OwnerKey, p2.OwnerKey))
s.Equal(p1.NickName, p2.NickName)
s.Equal(p1.Url, p2.Url)
s.Equal(p1.Location, p2.Location)
@@ -727,7 +727,7 @@ func (s *transactionSuite) TestCRCouncilMemberClaimNode_SerializeDeserialize() {
func crpPayloadEqual(payload1 *payload.CRCProposal, payload2 *payload.CRCProposal) bool {
return payload1.ProposalType == payload2.ProposalType &&
- bytes.Equal(payload1.OwnerPublicKey, payload2.OwnerPublicKey) &&
+ bytes.Equal(payload1.OwnerKey, payload2.OwnerKey) &&
payload1.CRCouncilMemberDID.IsEqual(payload2.CRCouncilMemberDID) &&
payload1.DraftHash.IsEqual(payload2.DraftHash) &&
bytes.Equal(payload1.Signature, payload2.Signature) &&
@@ -736,8 +736,8 @@ func crpPayloadEqual(payload1 *payload.CRCProposal, payload2 *payload.CRCProposa
func crpPayloadChangeProposalOwnerEqual(payload1 *payload.CRCProposal, payload2 *payload.CRCProposal) bool {
return payload1.ProposalType == payload2.ProposalType &&
- bytes.Equal(payload1.OwnerPublicKey, payload2.OwnerPublicKey) &&
- bytes.Equal(payload1.NewOwnerPublicKey, payload2.NewOwnerPublicKey) &&
+ bytes.Equal(payload1.OwnerKey, payload2.OwnerKey) &&
+ bytes.Equal(payload1.NewOwnerKey, payload2.NewOwnerKey) &&
payload1.DraftHash.IsEqual(payload2.DraftHash) &&
payload1.Recipient.IsEqual(payload2.Recipient) &&
payload1.TargetProposalHash.IsEqual(payload2.TargetProposalHash) &&
@@ -748,7 +748,7 @@ func crpPayloadChangeProposalOwnerEqual(payload1 *payload.CRCProposal, payload2
func crpPayloadCloseProposalEqual(payload1 *payload.CRCProposal, payload2 *payload.CRCProposal) bool {
return payload1.ProposalType == payload2.ProposalType &&
- bytes.Equal(payload1.OwnerPublicKey, payload2.OwnerPublicKey) &&
+ bytes.Equal(payload1.OwnerKey, payload2.OwnerKey) &&
payload1.CRCouncilMemberDID.IsEqual(payload2.CRCouncilMemberDID) &&
payload1.DraftHash.IsEqual(payload2.DraftHash) &&
payload1.TargetProposalHash.IsEqual(payload2.TargetProposalHash) &&
@@ -764,7 +764,7 @@ func crpPayloadReservedCustomIDEqual(payload1 *payload.CRCProposal, payload2 *pa
}
return payload1.ProposalType == payload2.ProposalType &&
- bytes.Equal(payload1.OwnerPublicKey, payload2.OwnerPublicKey) &&
+ bytes.Equal(payload1.OwnerKey, payload2.OwnerKey) &&
payload1.CRCouncilMemberDID.IsEqual(payload2.CRCouncilMemberDID) &&
payload1.DraftHash.IsEqual(payload2.DraftHash) &&
bytes.Equal(payload1.Signature, payload2.Signature) &&
@@ -779,7 +779,7 @@ func crpPayloadReceivedCustomIDEqual(payload1 *payload.CRCProposal, payload2 *pa
}
return payload1.ProposalType == payload2.ProposalType &&
- bytes.Equal(payload1.OwnerPublicKey, payload2.OwnerPublicKey) &&
+ bytes.Equal(payload1.OwnerKey, payload2.OwnerKey) &&
payload1.CRCouncilMemberDID.IsEqual(payload2.CRCouncilMemberDID) &&
payload1.DraftHash.IsEqual(payload2.DraftHash) &&
bytes.Equal(payload1.Signature, payload2.Signature) &&
@@ -861,8 +861,8 @@ func ctpPayloadEqual(payload1 *payload.CRCProposalTracking, payload2 *payload.CR
payload1.MessageHash.IsEqual(payload2.MessageHash) &&
payload1.SecretaryGeneralOpinionHash.IsEqual(payload2.SecretaryGeneralOpinionHash) &&
payload1.Stage == payload2.Stage &&
- bytes.Equal(payload1.OwnerPublicKey, payload2.OwnerPublicKey) &&
- bytes.Equal(payload1.NewOwnerPublicKey, payload2.NewOwnerPublicKey) &&
+ bytes.Equal(payload1.OwnerKey, payload2.OwnerKey) &&
+ bytes.Equal(payload1.NewOwnerKey, payload2.NewOwnerKey) &&
bytes.Equal(payload1.OwnerSignature, payload2.OwnerSignature) &&
bytes.Equal(payload1.NewOwnerSignature, payload2.NewOwnerSignature) &&
bytes.Equal(payload1.SecretaryGeneralSignature, payload2.SecretaryGeneralSignature)
@@ -1016,7 +1016,7 @@ func randomUnregisterCRPayload() *payload.UnregisterCR {
func createCRCProposalPayload(proposalType payload.CRCProposalType) *payload.CRCProposal {
return &payload.CRCProposal{
ProposalType: proposalType,
- OwnerPublicKey: randomBytes(33),
+ OwnerKey: randomBytes(33),
CRCouncilMemberDID: *randomUint168(),
DraftHash: *randomUint256(),
TargetProposalHash: *randomUint256(),
@@ -1040,8 +1040,8 @@ func randomCRCProposalTrackingPayload() *payload.CRCProposalTracking {
ProposalHash: *randomUint256(),
MessageHash: *randomUint256(),
Stage: randomUint8(),
- OwnerPublicKey: randomBytes(33),
- NewOwnerPublicKey: randomBytes(35),
+ OwnerKey: randomBytes(33),
+ NewOwnerKey: randomBytes(35),
OwnerSignature: randomBytes(64),
NewOwnerSignature: randomBytes(64),
SecretaryGeneralSignature: randomBytes(64),
diff --git a/test/unit/txvalidator_test.go b/test/unit/txvalidator_test.go
index 30114ee65..82010fc9f 100644
--- a/test/unit/txvalidator_test.go
+++ b/test/unit/txvalidator_test.go
@@ -73,6 +73,8 @@ func (s *txValidatorTestSuite) SetupSuite() {
params := &config.DefaultParams
params.Sterilize()
params.DPoSV2StartHeight = 0
+ params.GenesisBlock = core.GenesisBlock(*params.FoundationProgramHash)
+
blockchain.FoundationAddress = *params.FoundationProgramHash
s.foundationAddress = *params.FoundationProgramHash
@@ -873,12 +875,12 @@ func (s *txValidatorTestSuite) TestCheckRegisterProducerTransaction() {
errPublicKey, _ := common.HexStringToBytes(errPublicKeyStr)
rpPayload := &payload.ProducerInfo{
- OwnerPublicKey: publicKey1,
- NodePublicKey: publicKey1,
- NickName: "nickname 1",
- Url: "http://www.elastos_test.com",
- Location: 1,
- NetAddress: "127.0.0.1:20338",
+ OwnerKey: publicKey1,
+ NodePublicKey: publicKey1,
+ NickName: "nickname 1",
+ Url: "http://www.elastos_test.com",
+ Location: 1,
+ NetAddress: "127.0.0.1:20338",
}
rpSignBuf := new(bytes.Buffer)
err := rpPayload.SerializeUnsigned(rpSignBuf, payload.ProducerInfoVersion)
@@ -914,7 +916,7 @@ func (s *txValidatorTestSuite) TestCheckRegisterProducerTransaction() {
s.NoError(err)
// Give an invalid owner public key in payload
- txn.Payload().(*payload.ProducerInfo).OwnerPublicKey = errPublicKey
+ txn.Payload().(*payload.ProducerInfo).OwnerKey = errPublicKey
err, _ = txn.SpecialContextCheck()
s.EqualError(err, "transaction validate error: payload content invalid:invalid owner public key in payload")
@@ -927,7 +929,7 @@ func (s *txValidatorTestSuite) TestCheckRegisterProducerTransaction() {
s.EqualError(err, "transaction validate error: payload content invalid:invalid node public key in payload")
// check node public key same with CRC
- txn.Payload().(*payload.ProducerInfo).OwnerPublicKey = publicKey2
+ txn.Payload().(*payload.ProducerInfo).OwnerKey = publicKey2
pk, _ := common.HexStringToBytes(config.DefaultParams.DPoSConfiguration.CRCArbiters[0])
txn.Payload().(*payload.ProducerInfo).NodePublicKey = pk
config.DefaultParams.PublicDPOSHeight = 0
@@ -938,20 +940,20 @@ func (s *txValidatorTestSuite) TestCheckRegisterProducerTransaction() {
// check owner public key same with CRC
txn.Payload().(*payload.ProducerInfo).NodePublicKey = publicKey2
pk, _ = common.HexStringToBytes(config.DefaultParams.DPoSConfiguration.CRCArbiters[0])
- txn.Payload().(*payload.ProducerInfo).OwnerPublicKey = pk
+ txn.Payload().(*payload.ProducerInfo).OwnerKey = pk
config.DefaultParams.PublicDPOSHeight = 0
err, _ = txn.SpecialContextCheck()
config.DefaultParams.PublicDPOSHeight = originHeight
s.EqualError(err, "transaction validate error: payload content invalid:owner public key can't equal with CRC")
// Invalidates the signature in payload
- txn.Payload().(*payload.ProducerInfo).OwnerPublicKey = publicKey2
+ txn.Payload().(*payload.ProducerInfo).OwnerKey = publicKey2
txn.Payload().(*payload.ProducerInfo).NodePublicKey = publicKey2
err, _ = txn.SpecialContextCheck()
s.EqualError(err, "transaction validate error: payload content invalid:invalid signature in payload")
// Give a mismatching deposit address
- rpPayload.OwnerPublicKey = publicKey1
+ rpPayload.OwnerKey = publicKey1
rpPayload.Url = "www.test.com"
rpSignBuf = new(bytes.Buffer)
err = rpPayload.SerializeUnsigned(rpSignBuf, payload.ProducerInfoVersion)
@@ -1010,13 +1012,13 @@ func (s *txValidatorTestSuite) TestCheckRegisterDposV2ProducerTransaction() {
errPublicKey, _ := common.HexStringToBytes(errPublicKeyStr)
rpPayload := &payload.ProducerInfo{
- OwnerPublicKey: publicKey1,
- NodePublicKey: publicKey1,
- NickName: "nickname 1",
- Url: "http://www.elastos_test.com",
- Location: 1,
- NetAddress: "127.0.0.1:20338",
- StakeUntil: 100000,
+ OwnerKey: publicKey1,
+ NodePublicKey: publicKey1,
+ NickName: "nickname 1",
+ Url: "http://www.elastos_test.com",
+ Location: 1,
+ NetAddress: "127.0.0.1:20338",
+ StakeUntil: 100000,
}
rpSignBuf := new(bytes.Buffer)
err := rpPayload.SerializeUnsigned(rpSignBuf, payload.ProducerInfoDposV2Version)
@@ -1063,7 +1065,7 @@ func (s *txValidatorTestSuite) TestCheckRegisterDposV2ProducerTransaction() {
s.NoError(err)
// Give an invalid owner public key in payload
- txn.Payload().(*payload.ProducerInfo).OwnerPublicKey = errPublicKey
+ txn.Payload().(*payload.ProducerInfo).OwnerKey = errPublicKey
err, _ = tx.SpecialContextCheck()
s.EqualError(err.(errors.ELAError).InnerError(), "invalid owner public key in payload")
@@ -1072,12 +1074,12 @@ func (s *txValidatorTestSuite) TestCheckRegisterDposV2ProducerTransaction() {
{}, {}, {}, {},
}
param.PublicDPOSHeight = 1
- txn.Payload().(*payload.ProducerInfo).OwnerPublicKey = publicKey1
+ txn.Payload().(*payload.ProducerInfo).OwnerKey = publicKey1
err, _ = tx.SpecialContextCheck()
s.EqualError(err.(errors.ELAError).InnerError(), "can not register dposv2 before dposv2 start height")
// Invalidates public key in payload
- txn.Payload().(*payload.ProducerInfo).OwnerPublicKey = publicKey2
+ txn.Payload().(*payload.ProducerInfo).OwnerKey = publicKey2
txn.Payload().(*payload.ProducerInfo).NodePublicKey = publicKey2
param.PublicDPOSHeight = 5
s.Chain.Nodes = []*blockchain.BlockNode{
@@ -1087,7 +1089,7 @@ func (s *txValidatorTestSuite) TestCheckRegisterDposV2ProducerTransaction() {
s.EqualError(err.(errors.ELAError).InnerError(), "invalid signature in payload")
// Give a insufficient deposit coin
- txn.Payload().(*payload.ProducerInfo).OwnerPublicKey = publicKey1
+ txn.Payload().(*payload.ProducerInfo).OwnerKey = publicKey1
txn.Payload().(*payload.ProducerInfo).NodePublicKey = publicKey1
txn.SetOutputs([]*common2.Output{{
AssetID: common.Uint256{},
@@ -1162,8 +1164,12 @@ func (s *txValidatorTestSuite) TestCheckStakeTransaction() {
Parameter: nil,
}},
)
+ txn.SetParameters(&transaction.TransactionParameters{
+ BlockChain: s.Chain,
+ Config: s.Chain.GetParams(),
+ })
err := txn.CheckTransactionOutput()
- s.EqualError(err, "output count should not be greater than 2")
+ //s.EqualError(err, "output count should not be greater than 2")
txn = functions.CreateTransaction(
0,
@@ -1179,6 +1185,10 @@ func (s *txValidatorTestSuite) TestCheckStakeTransaction() {
Parameter: nil,
}},
)
+ txn.SetParameters(&transaction.TransactionParameters{
+ BlockChain: s.Chain,
+ Config: s.Chain.GetParams(),
+ })
err = txn.CheckTransactionOutput()
s.EqualError(err, "transaction has no outputs")
@@ -1204,6 +1214,10 @@ func (s *txValidatorTestSuite) TestCheckStakeTransaction() {
Parameter: nil,
}},
)
+ txn.SetParameters(&transaction.TransactionParameters{
+ BlockChain: s.Chain,
+ Config: s.Chain.GetParams(),
+ })
err = txn.CheckTransactionOutput()
s.EqualError(err, "asset ID in output is invalid")
@@ -1229,6 +1243,10 @@ func (s *txValidatorTestSuite) TestCheckStakeTransaction() {
Parameter: nil,
}},
)
+ txn.SetParameters(&transaction.TransactionParameters{
+ BlockChain: s.Chain,
+ Config: s.Chain.GetParams(),
+ })
err = txn.CheckTransactionOutput()
s.EqualError(err, "invalid transaction UTXO output")
@@ -1254,6 +1272,10 @@ func (s *txValidatorTestSuite) TestCheckStakeTransaction() {
Parameter: nil,
}},
)
+ txn.SetParameters(&transaction.TransactionParameters{
+ BlockChain: s.Chain,
+ Config: s.Chain.GetParams(),
+ })
err = txn.CheckTransactionOutput()
s.EqualError(err, "invalid output type")
@@ -1281,6 +1303,10 @@ func (s *txValidatorTestSuite) TestCheckStakeTransaction() {
Parameter: nil,
}},
)
+ txn.SetParameters(&transaction.TransactionParameters{
+ BlockChain: s.Chain,
+ Config: s.Chain.GetParams(),
+ })
err = txn.CheckTransactionOutput()
s.EqualError(err, "invalid exchange vote version")
@@ -1856,12 +1882,12 @@ func (s *txValidatorTestSuite) TestCheckRegisterProducerTransaction2() {
errorPrefix := "transaction validate error: payload content invalid:"
registerProducer := func() {
registerPayload := &payload.ProducerInfo{
- OwnerPublicKey: publicKey1,
- NodePublicKey: publicKey3,
- NickName: "producer1",
- Url: "url1",
- Location: 1,
- NetAddress: "",
+ OwnerKey: publicKey1,
+ NodePublicKey: publicKey3,
+ NickName: "producer1",
+ Url: "url1",
+ Location: 1,
+ NetAddress: "",
}
txn := getRegisterProducerTX(publicKeyStr1, registerPayload, s.Chain)
s.CurrentHeight = 1
@@ -1899,39 +1925,39 @@ func (s *txValidatorTestSuite) TestCheckRegisterProducerTransaction2() {
}
//register and process
registerProducer()
- // OwnerPublicKey is already other's NodePublicKey
+ // OwnerKey is already other's NodePublicKey
ownerPublicKeyIsOtherNodePublicKey := func() {
registerPayload := &payload.ProducerInfo{
- OwnerPublicKey: publicKey3,
- NodePublicKey: publicKey2,
- NickName: "producer2",
- Url: "url1",
- Location: 1,
- NetAddress: "",
+ OwnerKey: publicKey3,
+ NodePublicKey: publicKey2,
+ NickName: "producer2",
+ Url: "url1",
+ Location: 1,
+ NetAddress: "",
}
txn := getRegisterProducerTX(publicKeyStr3, registerPayload, s.Chain)
s.CurrentHeight = 2
err, _ := txn.SpecialContextCheck()
s.EqualError(err,
- errorPrefix+"OwnerPublicKey is already other's NodePublicKey")
+ errorPrefix+"OwnerKey is already other's NodePublicKey")
}
ownerPublicKeyIsOtherNodePublicKey()
- // NodePublicKey is already other's OwnerPublicKey
+ // NodePublicKey is already other's OwnerKey
nodePublicKeyIsOtherOwnerPublicKey := func() {
registerPayload := &payload.ProducerInfo{
- OwnerPublicKey: publicKey2,
- NodePublicKey: publicKey1,
- NickName: "producer2",
- Url: "url1",
- Location: 1,
- NetAddress: "",
+ OwnerKey: publicKey2,
+ NodePublicKey: publicKey1,
+ NickName: "producer2",
+ Url: "url1",
+ Location: 1,
+ NetAddress: "",
}
txn := getRegisterProducerTX(publicKeyStr2, registerPayload, s.Chain)
err, _ := txn.SpecialContextCheck()
s.EqualError(err,
- errorPrefix+"NodePublicKey is already other's OwnerPublicKey")
+ errorPrefix+"NodePublicKey is already other's OwnerKey")
}
nodePublicKeyIsOtherOwnerPublicKey()
@@ -1947,12 +1973,12 @@ func (s *txValidatorTestSuite) TestCheckRegisterProducerTransaction2() {
//wrong nickname
wrongNickName := func() {
registerPayload := &payload.ProducerInfo{
- OwnerPublicKey: publicKey2,
- NodePublicKey: publicKey1,
- NickName: "",
- Url: "url1",
- Location: 1,
- NetAddress: "",
+ OwnerKey: publicKey2,
+ NodePublicKey: publicKey1,
+ NickName: "",
+ Url: "url1",
+ Location: 1,
+ NetAddress: "",
}
txn := getRegisterProducerTX(publicKeyStr3, registerPayload, s.Chain)
err, _ := txn.SpecialContextCheck()
@@ -1963,12 +1989,12 @@ func (s *txValidatorTestSuite) TestCheckRegisterProducerTransaction2() {
//wrong url
wrongURL := func() {
registerPayload := &payload.ProducerInfo{
- OwnerPublicKey: publicKey2,
- NodePublicKey: publicKey1,
- NickName: "NickName",
- Url: randomUrl(),
- Location: 1,
- NetAddress: "",
+ OwnerKey: publicKey2,
+ NodePublicKey: publicKey1,
+ NickName: "NickName",
+ Url: randomUrl(),
+ Location: 1,
+ NetAddress: "",
}
txn := getRegisterProducerTX(publicKeyStr3, registerPayload, s.Chain)
err, _ := txn.SpecialContextCheck()
@@ -1979,12 +2005,12 @@ func (s *txValidatorTestSuite) TestCheckRegisterProducerTransaction2() {
// check duplication of node public key.
duplicateNodePublcKey := func() {
registerPayload := &payload.ProducerInfo{
- OwnerPublicKey: publicKey2,
- NodePublicKey: publicKey3,
- NickName: "NickName",
- Url: "",
- Location: 1,
- NetAddress: "",
+ OwnerKey: publicKey2,
+ NodePublicKey: publicKey3,
+ NickName: "NickName",
+ Url: "",
+ Location: 1,
+ NetAddress: "",
}
txn := getRegisterProducerTX(publicKeyStr3, registerPayload, s.Chain)
err, _ := txn.SpecialContextCheck()
@@ -1995,12 +2021,12 @@ func (s *txValidatorTestSuite) TestCheckRegisterProducerTransaction2() {
// check duplication of owner public key.
duplicateOwnerPublcKey := func() {
registerPayload := &payload.ProducerInfo{
- OwnerPublicKey: publicKey1,
- NodePublicKey: publicKey5,
- NickName: "NickName",
- Url: "",
- Location: 1,
- NetAddress: "",
+ OwnerKey: publicKey1,
+ NodePublicKey: publicKey5,
+ NickName: "NickName",
+ Url: "",
+ Location: 1,
+ NetAddress: "",
}
txn := getRegisterProducerTX(publicKeyStr1, registerPayload, s.Chain)
err, _ := txn.SpecialContextCheck()
@@ -2012,12 +2038,12 @@ func (s *txValidatorTestSuite) TestCheckRegisterProducerTransaction2() {
// check duplication of nickname.
duplicateNickName := func() {
registerPayload := &payload.ProducerInfo{
- OwnerPublicKey: publicKey2,
- NodePublicKey: publicKey2,
- NickName: "producer1",
- Url: "",
- Location: 1,
- NetAddress: "",
+ OwnerKey: publicKey2,
+ NodePublicKey: publicKey2,
+ NickName: "producer1",
+ Url: "",
+ Location: 1,
+ NetAddress: "",
}
txn := getRegisterProducerTX(publicKeyStr3, registerPayload, s.Chain)
err, _ := txn.SpecialContextCheck()
@@ -2028,12 +2054,12 @@ func (s *txValidatorTestSuite) TestCheckRegisterProducerTransaction2() {
//owner public key is already exist in cr list
ownerKeyInCrList := func() {
registerPayload := &payload.ProducerInfo{
- OwnerPublicKey: publicKey2,
- NodePublicKey: publicKey2,
- NickName: "producer111",
- Url: "",
- Location: 1,
- NetAddress: "",
+ OwnerKey: publicKey2,
+ NodePublicKey: publicKey2,
+ NickName: "producer111",
+ Url: "",
+ Location: 1,
+ NetAddress: "",
}
//add cr
code := getCode(publicKey2)
@@ -2052,12 +2078,12 @@ func (s *txValidatorTestSuite) TestCheckRegisterProducerTransaction2() {
//node public key is already exist in cr list
nodePublicKeyInCrList := func() {
registerPayload := &payload.ProducerInfo{
- OwnerPublicKey: publicKey4,
- NodePublicKey: publicKey5,
- NickName: "producer111",
- Url: "",
- Location: 1,
- NetAddress: "",
+ OwnerKey: publicKey4,
+ NodePublicKey: publicKey5,
+ NickName: "producer111",
+ Url: "",
+ Location: 1,
+ NetAddress: "",
}
//add cr
code := getCode(publicKey5)
@@ -2075,12 +2101,12 @@ func (s *txValidatorTestSuite) TestCheckRegisterProducerTransaction2() {
//can not register dposv1 after dposv2 active height
noRegisterDPOSV1 := func() {
registerPayload := &payload.ProducerInfo{
- OwnerPublicKey: publicKey5,
- NodePublicKey: publicKey4,
- NickName: "producer111",
- Url: "",
- Location: 1,
- NetAddress: "",
+ OwnerKey: publicKey5,
+ NodePublicKey: publicKey4,
+ NickName: "producer111",
+ Url: "",
+ Location: 1,
+ NetAddress: "",
}
//
signedBuf := new(bytes.Buffer)
@@ -2154,12 +2180,12 @@ func (s *txValidatorTestSuite) TestCheckUpdateProducerTransaction() {
errPublicKey, _ := common.HexStringToBytes(errPublicKeyStr)
registerPayload := &payload.ProducerInfo{
- OwnerPublicKey: publicKey1,
- NodePublicKey: publicKey1,
- NickName: "",
- Url: "",
- Location: 1,
- NetAddress: "",
+ OwnerKey: publicKey1,
+ NodePublicKey: publicKey1,
+ NickName: "",
+ Url: "",
+ Location: 1,
+ NetAddress: "",
}
programs := []*program.Program{{
Code: getCodeByPubKeyStr(publicKeyStr1),
@@ -2210,12 +2236,12 @@ func (s *txValidatorTestSuite) TestCheckUpdateProducerTransaction() {
txn.SetTxType(common2.UpdateProducer)
updatePayload := &payload.ProducerInfo{
- OwnerPublicKey: publicKey1,
- NodePublicKey: publicKey1,
- NickName: "",
- Url: "",
- Location: 2,
- NetAddress: "",
+ OwnerKey: publicKey1,
+ NodePublicKey: publicKey1,
+ NickName: "",
+ Url: "",
+ Location: 2,
+ NetAddress: "",
}
txn.SetPayload(updatePayload)
s.CurrentHeight++
@@ -2227,7 +2253,7 @@ func (s *txValidatorTestSuite) TestCheckUpdateProducerTransaction() {
updatePayload.NickName = "nick name"
updatePayload.Url = "www.elastos.org"
- updatePayload.OwnerPublicKey = errPublicKey
+ updatePayload.OwnerKey = errPublicKey
err, _ = txn.SpecialContextCheck()
s.EqualError(err, "transaction validate error: payload content invalid:invalid owner public key in payload")
@@ -2240,7 +2266,7 @@ func (s *txValidatorTestSuite) TestCheckUpdateProducerTransaction() {
config.DefaultParams.PublicDPOSHeight = originHeight
// check node public key same with CRC
- txn.Payload().(*payload.ProducerInfo).OwnerPublicKey = publicKey2
+ txn.Payload().(*payload.ProducerInfo).OwnerKey = publicKey2
pk, _ := common.HexStringToBytes(config.DefaultParams.DPoSConfiguration.CRCArbiters[0])
txn.Payload().(*payload.ProducerInfo).NodePublicKey = pk
config.DefaultParams.PublicDPOSHeight = 0
@@ -2251,18 +2277,18 @@ func (s *txValidatorTestSuite) TestCheckUpdateProducerTransaction() {
// check owner public key same with CRC
txn.Payload().(*payload.ProducerInfo).NodePublicKey = publicKey2
pk, _ = common.HexStringToBytes(config.DefaultParams.DPoSConfiguration.CRCArbiters[0])
- txn.Payload().(*payload.ProducerInfo).OwnerPublicKey = pk
+ txn.Payload().(*payload.ProducerInfo).OwnerKey = pk
config.DefaultParams.PublicDPOSHeight = 0
err, _ = txn.SpecialContextCheck()
config.DefaultParams.PublicDPOSHeight = originHeight
s.EqualError(err, "transaction validate error: payload content invalid:invalid signature in payload")
- updatePayload.OwnerPublicKey = publicKey2
+ updatePayload.OwnerKey = publicKey2
updatePayload.NodePublicKey = publicKey1
err, _ = txn.SpecialContextCheck()
s.EqualError(err, "transaction validate error: payload content invalid:invalid signature in payload")
- updatePayload.OwnerPublicKey = publicKey1
+ updatePayload.OwnerKey = publicKey1
updateSignBuf := new(bytes.Buffer)
err1 := updatePayload.SerializeUnsigned(updateSignBuf, payload.ProducerInfoVersion)
s.NoError(err1)
@@ -2286,12 +2312,12 @@ func (s *txValidatorTestSuite) TestCheckUpdateProducerV1V2Transaction() {
errPublicKey, _ := common.HexStringToBytes(errPublicKeyStr)
registerPayload := &payload.ProducerInfo{
- OwnerPublicKey: publicKey1,
- NodePublicKey: publicKey1,
- NickName: "",
- Url: "",
- Location: 1,
- NetAddress: "",
+ OwnerKey: publicKey1,
+ NodePublicKey: publicKey1,
+ NickName: "",
+ Url: "",
+ Location: 1,
+ NetAddress: "",
}
programs := []*program.Program{{
Code: getCodeByPubKeyStr(publicKeyStr1),
@@ -2343,13 +2369,13 @@ func (s *txValidatorTestSuite) TestCheckUpdateProducerV1V2Transaction() {
txn.SetTxType(common2.UpdateProducer)
updatePayload := &payload.ProducerInfo{
- OwnerPublicKey: publicKey1,
- NodePublicKey: publicKey1,
- NickName: "",
- Url: "",
- Location: 2,
- NetAddress: "",
- StakeUntil: 10,
+ OwnerKey: publicKey1,
+ NodePublicKey: publicKey1,
+ NickName: "",
+ Url: "",
+ Location: 2,
+ NetAddress: "",
+ StakeUntil: 10,
}
txn.SetPayload(updatePayload)
s.CurrentHeight++
@@ -2361,7 +2387,7 @@ func (s *txValidatorTestSuite) TestCheckUpdateProducerV1V2Transaction() {
updatePayload.NickName = "nick name"
updatePayload.Url = "www.elastos.org"
- updatePayload.OwnerPublicKey = errPublicKey
+ updatePayload.OwnerKey = errPublicKey
err, _ = txn.SpecialContextCheck()
s.EqualError(err, "transaction validate error: payload content invalid:invalid owner public key in payload")
@@ -2374,7 +2400,7 @@ func (s *txValidatorTestSuite) TestCheckUpdateProducerV1V2Transaction() {
config.DefaultParams.PublicDPOSHeight = originHeight
// check node public key same with CRC
- txn.Payload().(*payload.ProducerInfo).OwnerPublicKey = publicKey2
+ txn.Payload().(*payload.ProducerInfo).OwnerKey = publicKey2
pk, _ := common.HexStringToBytes(config.DefaultParams.DPoSConfiguration.CRCArbiters[0])
txn.Payload().(*payload.ProducerInfo).NodePublicKey = pk
config.DefaultParams.PublicDPOSHeight = 0
@@ -2385,18 +2411,18 @@ func (s *txValidatorTestSuite) TestCheckUpdateProducerV1V2Transaction() {
// check owner public key same with CRC
txn.Payload().(*payload.ProducerInfo).NodePublicKey = publicKey2
pk, _ = common.HexStringToBytes(config.DefaultParams.DPoSConfiguration.CRCArbiters[0])
- txn.Payload().(*payload.ProducerInfo).OwnerPublicKey = pk
+ txn.Payload().(*payload.ProducerInfo).OwnerKey = pk
config.DefaultParams.PublicDPOSHeight = 0
err, _ = txn.SpecialContextCheck()
config.DefaultParams.PublicDPOSHeight = originHeight
s.EqualError(err, "transaction validate error: payload content invalid:invalid signature in payload")
- updatePayload.OwnerPublicKey = publicKey2
+ updatePayload.OwnerKey = publicKey2
updatePayload.NodePublicKey = publicKey1
err, _ = txn.SpecialContextCheck()
s.EqualError(err, "transaction validate error: payload content invalid:invalid signature in payload")
- updatePayload.OwnerPublicKey = publicKey1
+ updatePayload.OwnerKey = publicKey1
updateSignBuf := new(bytes.Buffer)
err1 := updatePayload.SerializeUnsigned(updateSignBuf, payload.ProducerInfoVersion)
s.NoError(err1)
@@ -2450,13 +2476,13 @@ func (s *txValidatorTestSuite) TestCheckUpdateProducerV2Transaction() {
errPublicKey, _ := common.HexStringToBytes(errPublicKeyStr)
registerPayload := &payload.ProducerInfo{
- OwnerPublicKey: publicKey1,
- NodePublicKey: publicKey1,
- NickName: "",
- Url: "",
- Location: 1,
- NetAddress: "",
- StakeUntil: 100,
+ OwnerKey: publicKey1,
+ NodePublicKey: publicKey1,
+ NickName: "",
+ Url: "",
+ Location: 1,
+ NetAddress: "",
+ StakeUntil: 100,
}
programs := []*program.Program{{
Code: getCodeByPubKeyStr(publicKeyStr1),
@@ -2508,13 +2534,13 @@ func (s *txValidatorTestSuite) TestCheckUpdateProducerV2Transaction() {
txn.SetTxType(common2.UpdateProducer)
updatePayload := &payload.ProducerInfo{
- OwnerPublicKey: publicKey1,
- NodePublicKey: publicKey1,
- NickName: "",
- Url: "",
- Location: 2,
- NetAddress: "",
- StakeUntil: 1000,
+ OwnerKey: publicKey1,
+ NodePublicKey: publicKey1,
+ NickName: "",
+ Url: "",
+ Location: 2,
+ NetAddress: "",
+ StakeUntil: 1000,
}
txn.SetPayload(updatePayload)
s.CurrentHeight++
@@ -2526,7 +2552,7 @@ func (s *txValidatorTestSuite) TestCheckUpdateProducerV2Transaction() {
updatePayload.NickName = "nick name"
updatePayload.Url = "www.elastos.org"
- updatePayload.OwnerPublicKey = errPublicKey
+ updatePayload.OwnerKey = errPublicKey
err, _ = txn.SpecialContextCheck()
s.EqualError(err, "transaction validate error: payload content invalid:invalid owner public key in payload")
@@ -2539,7 +2565,7 @@ func (s *txValidatorTestSuite) TestCheckUpdateProducerV2Transaction() {
config.DefaultParams.PublicDPOSHeight = originHeight
// check node public key same with CRC
- txn.Payload().(*payload.ProducerInfo).OwnerPublicKey = publicKey2
+ txn.Payload().(*payload.ProducerInfo).OwnerKey = publicKey2
pk, _ := common.HexStringToBytes(config.DefaultParams.DPoSConfiguration.CRCArbiters[0])
txn.Payload().(*payload.ProducerInfo).NodePublicKey = pk
config.DefaultParams.PublicDPOSHeight = 0
@@ -2550,18 +2576,18 @@ func (s *txValidatorTestSuite) TestCheckUpdateProducerV2Transaction() {
// check owner public key same with CRC
txn.Payload().(*payload.ProducerInfo).NodePublicKey = publicKey2
pk, _ = common.HexStringToBytes(config.DefaultParams.DPoSConfiguration.CRCArbiters[0])
- txn.Payload().(*payload.ProducerInfo).OwnerPublicKey = pk
+ txn.Payload().(*payload.ProducerInfo).OwnerKey = pk
config.DefaultParams.PublicDPOSHeight = 0
err, _ = txn.SpecialContextCheck()
config.DefaultParams.PublicDPOSHeight = originHeight
s.EqualError(err, "transaction validate error: payload content invalid:invalid signature in payload")
- updatePayload.OwnerPublicKey = publicKey2
+ updatePayload.OwnerKey = publicKey2
updatePayload.NodePublicKey = publicKey1
err, _ = txn.SpecialContextCheck()
s.EqualError(err, "transaction validate error: payload content invalid:invalid signature in payload")
- updatePayload.OwnerPublicKey = publicKey1
+ updatePayload.OwnerKey = publicKey1
updateSignBuf := new(bytes.Buffer)
err1 := updatePayload.SerializeUnsigned(updateSignBuf, payload.ProducerInfoVersion)
s.NoError(err1)
@@ -2602,7 +2628,7 @@ func (s *txValidatorTestSuite) TestCheckCancelProducerTransaction() {
errPublicKey, _ := common.HexStringToBytes(errPublicKeyStr)
cancelPayload := &payload.ProcessProducer{
- OwnerPublicKey: publicKey1,
+ OwnerKey: publicKey1,
}
programs := []*program.Program{{
@@ -2622,17 +2648,17 @@ func (s *txValidatorTestSuite) TestCheckCancelProducerTransaction() {
programs,
)
- cancelPayload.OwnerPublicKey = errPublicKey
+ cancelPayload.OwnerKey = errPublicKey
txn = CreateTransactionByType(txn, s.Chain)
err, _ := txn.SpecialContextCheck()
s.EqualError(err, "transaction validate error: payload content invalid:invalid public key in payload")
- cancelPayload.OwnerPublicKey = publicKey2
+ cancelPayload.OwnerKey = publicKey2
err, _ = txn.SpecialContextCheck()
s.EqualError(err, "transaction validate error: payload content invalid:invalid signature in payload")
buf := new(bytes.Buffer)
- cancelPayload.OwnerPublicKey = publicKey1
+ cancelPayload.OwnerKey = publicKey1
cancelPayload.SerializeUnsigned(buf, 0)
sig, _ := crypto.Sign(privateKey1, buf.Bytes())
@@ -2655,12 +2681,12 @@ func (s *txValidatorTestSuite) TestCheckCancelProducerTransaction() {
{
registerPayload := &payload.ProducerInfo{
- OwnerPublicKey: publicKey1,
- NodePublicKey: publicKey1,
- NickName: "",
- Url: "",
- Location: 1,
- NetAddress: "",
+ OwnerKey: publicKey1,
+ NodePublicKey: publicKey1,
+ NickName: "",
+ Url: "",
+ Location: 1,
+ NetAddress: "",
}
programs = []*program.Program{{
Code: getCodeByPubKeyStr(publicKeyStr1),
@@ -2716,13 +2742,13 @@ func (s *txValidatorTestSuite) TestCheckCancelProducerTransaction() {
{
registerPayload := &payload.ProducerInfo{
- OwnerPublicKey: publicKey1,
- NodePublicKey: publicKey1,
- NickName: "",
- Url: "",
- Location: 1,
- NetAddress: "",
- StakeUntil: 100,
+ OwnerKey: publicKey1,
+ NodePublicKey: publicKey1,
+ NickName: "",
+ Url: "",
+ Location: 1,
+ NetAddress: "",
+ StakeUntil: 100,
}
programs = []*program.Program{{
Code: getCodeByPubKeyStr(publicKeyStr1),
@@ -2778,12 +2804,12 @@ func (s *txValidatorTestSuite) TestCheckCancelProducerTransaction() {
{
registerPayload := &payload.ProducerInfo{
- OwnerPublicKey: publicKey1,
- NodePublicKey: publicKey1,
- NickName: "",
- Url: "",
- Location: 1,
- NetAddress: "",
+ OwnerKey: publicKey1,
+ NodePublicKey: publicKey1,
+ NickName: "",
+ Url: "",
+ Location: 1,
+ NetAddress: "",
}
programs = []*program.Program{{
Code: getCodeByPubKeyStr(publicKeyStr1),
@@ -2845,13 +2871,13 @@ func (s *txValidatorTestSuite) TestCheckCancelProducerTransaction() {
programs,
)
updatePayload := &payload.ProducerInfo{
- OwnerPublicKey: publicKey1,
- NodePublicKey: publicKey1,
- NickName: "nick name",
- Url: "www.elastos.org",
- Location: 2,
- NetAddress: "",
- StakeUntil: 10,
+ OwnerKey: publicKey1,
+ NodePublicKey: publicKey1,
+ NickName: "nick name",
+ Url: "www.elastos.org",
+ Location: 2,
+ NetAddress: "",
+ StakeUntil: 10,
}
txn2.SetPayload(updatePayload)
@@ -2953,12 +2979,12 @@ func (s *txValidatorTestSuite) TestCheckActivateProducerTransaction() {
{
registerPayload := &payload.ProducerInfo{
- OwnerPublicKey: publicKey1,
- NodePublicKey: publicKey1,
- NickName: "",
- Url: "",
- Location: 1,
- NetAddress: "",
+ OwnerKey: publicKey1,
+ NodePublicKey: publicKey1,
+ NickName: "",
+ Url: "",
+ Location: 1,
+ NetAddress: "",
}
programs = []*program.Program{{
Code: getCodeByPubKeyStr(publicKeyStr1),
@@ -3034,13 +3060,13 @@ func (s *txValidatorTestSuite) TestCheckActivateProducerTransaction() {
{
registerPayload := &payload.ProducerInfo{
- OwnerPublicKey: publicKey1,
- NodePublicKey: publicKey1,
- NickName: "",
- Url: "",
- Location: 1,
- NetAddress: "",
- StakeUntil: 100,
+ OwnerKey: publicKey1,
+ NodePublicKey: publicKey1,
+ NickName: "",
+ Url: "",
+ Location: 1,
+ NetAddress: "",
+ StakeUntil: 100,
}
programs = []*program.Program{{
Code: getCodeByPubKeyStr(publicKeyStr1),
@@ -3648,7 +3674,7 @@ func (s *txValidatorTestSuite) getSecretaryGeneralCRCProposalTx(ownerPublicKeySt
crcProposalPayload := &payload.CRCProposal{
ProposalType: payload.SecretaryGeneral,
CategoryData: "111",
- OwnerPublicKey: ownerPublicKey,
+ OwnerKey: ownerPublicKey,
DraftHash: common.Hash(draftData),
SecretaryGeneralPublicKey: secretaryPublicKey,
SecretaryGeneralDID: *secretaryGeneralDID,
@@ -3705,7 +3731,7 @@ func (s *txValidatorTestSuite) getCRCProposalTx(publicKeyStr, privateKeyStr,
did2, _ := blockchain.GetDIDFromCode(code2)
crcProposalPayload := &payload.CRCProposal{
ProposalType: payload.Normal,
- OwnerPublicKey: publicKey1,
+ OwnerKey: publicKey1,
CRCouncilMemberDID: *did2,
DraftHash: common.Hash(draftData),
Budgets: createBudgets(3),
@@ -3739,7 +3765,7 @@ func (s *txValidatorTestSuite) createSpecificStatusProposal(publicKey1, publicKe
CRCouncilMemberDID, _ := blockchain.GetDIDFromCode(code2)
proposal := &payload.CRCProposal{
ProposalType: proposalType,
- OwnerPublicKey: publicKey1,
+ OwnerKey: publicKey1,
CRCouncilMemberDID: *CRCouncilMemberDID,
DraftHash: common.Hash(draftData),
Budgets: createBudgets(3),
@@ -3767,7 +3793,7 @@ func (s *txValidatorTestSuite) createSpecificStatusProposal(publicKey1, publicKe
FinalPaymentStatus: false,
TrackingCount: 0,
TerminatedHeight: 0,
- ProposalOwner: proposal.OwnerPublicKey,
+ ProposalOwner: proposal.OwnerKey,
}
return proposalState, proposal
}
@@ -3799,7 +3825,7 @@ func (s *txValidatorTestSuite) getCRCCloseProposalTxWithHash(publicKeyStr, priva
CRCouncilMemberDID, _ := blockchain.GetDIDFromCode(code2)
crcProposalPayload := &payload.CRCProposal{
ProposalType: payload.CloseProposal,
- OwnerPublicKey: publicKey1,
+ OwnerKey: publicKey1,
CRCouncilMemberDID: *CRCouncilMemberDID,
DraftHash: common.Hash(draftData),
TargetProposalHash: closeProposalHash,
@@ -3846,7 +3872,7 @@ func (s *txValidatorTestSuite) getCRCRegisterSideChainProposalTx(publicKeyStr, p
CRCouncilMemberDID, _ := blockchain.GetDIDFromCode(getCodeByPubKeyStr(crPublicKeyStr))
crcProposalPayload := &payload.CRCProposal{
ProposalType: payload.RegisterSideChain,
- OwnerPublicKey: normalPublicKey,
+ OwnerKey: normalPublicKey,
CRCouncilMemberDID: *CRCouncilMemberDID,
DraftHash: common.Hash(draftData),
SideChainInfo: payload.SideChainInfo{
@@ -3904,7 +3930,7 @@ func (s *txValidatorTestSuite) getCRCCloseProposalTx(publicKeyStr, privateKeyStr
CRCouncilMemberDID, _ := blockchain.GetDIDFromCode(code2)
crcProposalPayload := &payload.CRCProposal{
ProposalType: payload.CloseProposal,
- OwnerPublicKey: publicKey2,
+ OwnerKey: publicKey2,
CRCouncilMemberDID: *CRCouncilMemberDID,
DraftHash: common.Hash(draftData),
TargetProposalHash: common.Hash(randomBytes(10)),
@@ -3967,7 +3993,7 @@ func (s *txValidatorTestSuite) getCRCReceivedCustomIDProposalTx(publicKeyStr, pr
CRCouncilMemberDID, _ := blockchain.GetDIDFromCode(code2)
crcProposalPayload := &payload.CRCProposal{
ProposalType: payload.ReceiveCustomID,
- OwnerPublicKey: publicKey1,
+ OwnerKey: publicKey1,
CRCouncilMemberDID: *CRCouncilMemberDID,
DraftHash: common.Hash(draftData),
ReceivedCustomIDList: receivedList,
@@ -4019,7 +4045,7 @@ func (s *txValidatorTestSuite) getCRCReservedCustomIDProposalTx(publicKeyStr, pr
CRCouncilMemberDID, _ := blockchain.GetDIDFromCode(code2)
crcProposalPayload := &payload.CRCProposal{
ProposalType: payload.ReserveCustomID,
- OwnerPublicKey: publicKey2,
+ OwnerKey: publicKey2,
CRCouncilMemberDID: *CRCouncilMemberDID,
DraftHash: common.Hash(draftData),
ReservedCustomIDList: []string{randomName(3), randomName(3), randomName(3)},
@@ -4068,7 +4094,7 @@ func (s *txValidatorTestSuite) TestCheckCRCProposalTrackingTransaction() {
pld := payload.CRCProposal{
ProposalType: 0,
- OwnerPublicKey: ownerPubKey,
+ OwnerKey: ownerPubKey,
CRCouncilMemberDID: *randomUint168(),
DraftHash: *randomUint256(),
Budgets: createBudgets(3),
@@ -4118,7 +4144,7 @@ func (s *txValidatorTestSuite) TestCheckCRCProposalTrackingTransaction() {
BlockChain: s.Chain,
})
err, _ = txn.SpecialContextCheck()
- s.EqualError(err, "transaction validate error: payload content invalid:the NewOwnerPublicKey need to be empty")
+ s.EqualError(err, "transaction validate error: payload content invalid:the NewOwnerKey need to be empty")
// Check Progress tracking tx.
txn = s.getCRCProposalTrackingTx(payload.Progress, *proposalHash, 1,
@@ -4147,7 +4173,7 @@ func (s *txValidatorTestSuite) TestCheckCRCProposalTrackingTransaction() {
BlockChain: s.Chain,
})
err, _ = txn.SpecialContextCheck()
- s.EqualError(err, "transaction validate error: payload content invalid:the NewOwnerPublicKey need to be empty")
+ s.EqualError(err, "transaction validate error: payload content invalid:the NewOwnerKey need to be empty")
// Check Terminated tracking tx.
txn = s.getCRCProposalTrackingTx(payload.Terminated, *proposalHash, 0,
@@ -4190,7 +4216,7 @@ func (s *txValidatorTestSuite) TestCheckCRCProposalTrackingTransaction() {
BlockChain: s.Chain,
})
err, _ = txn.SpecialContextCheck()
- s.EqualError(err, "transaction validate error: payload content invalid:the NewOwnerPublicKey need to be empty")
+ s.EqualError(err, "transaction validate error: payload content invalid:the NewOwnerKey need to be empty")
// Check ChangeOwner tracking tx.
txn = s.getCRCProposalTrackingTx(payload.ChangeOwner, *proposalHash, 0,
@@ -4257,7 +4283,7 @@ func (s *txValidatorTestSuite) TestCheckCRCProposalTrackingTransaction() {
// Check proposal status is not VoterAgreed.
pld = payload.CRCProposal{
ProposalType: 0,
- OwnerPublicKey: ownerPubKey,
+ OwnerKey: ownerPubKey,
CRCouncilMemberDID: *randomUint168(),
DraftHash: *randomUint256(),
Budgets: createBudgets(3),
@@ -4285,7 +4311,7 @@ func (s *txValidatorTestSuite) TestCheckCRCProposalTrackingTransaction() {
// Check reach max proposal tracking count.
pld = payload.CRCProposal{
ProposalType: 0,
- OwnerPublicKey: ownerPubKey,
+ OwnerKey: ownerPubKey,
CRCouncilMemberDID: *randomUint168(),
DraftHash: *randomUint256(),
Budgets: createBudgets(3),
@@ -4346,8 +4372,8 @@ func (s *txValidatorTestSuite) getCRCProposalTrackingTx(
ProposalHash: proposalHash,
Stage: stage,
MessageHash: common.Hash(documentData),
- OwnerPublicKey: ownerPublicKey,
- NewOwnerPublicKey: newownerpublickey,
+ OwnerKey: ownerPublicKey,
+ NewOwnerKey: newownerpublickey,
SecretaryGeneralOpinionHash: common.Hash(opinionHash),
}
@@ -5073,15 +5099,15 @@ func (s *txValidatorTestSuite) getCRCProposalWithdrawTx(crPublicKeyStr,
switch payloadVersion {
case 0x00:
crcProposalWithdraw = &payload.CRCProposalWithdraw{
- ProposalHash: *randomUint256(),
- OwnerPublicKey: pkBytes,
+ ProposalHash: *randomUint256(),
+ OwnerKey: pkBytes,
}
case 0x01:
crcProposalWithdraw = &payload.CRCProposalWithdraw{
- ProposalHash: *randomUint256(),
- OwnerPublicKey: pkBytes,
- Recipient: *recipient,
- Amount: recipAmout,
+ ProposalHash: *randomUint256(),
+ OwnerKey: pkBytes,
+ Recipient: *recipient,
+ Amount: recipAmout,
}
txn.SetPayloadVersion(payload.CRCProposalWithdrawVersion01)
}
@@ -5165,9 +5191,9 @@ func (s *txValidatorTestSuite) TestCheckCRCProposalWithdrawTransaction() {
Recipient, CRExpensesAddressU168, 9*ela, 50*ela, 0)
crcProposalWithdraw, _ := txn.Payload().(*payload.CRCProposalWithdraw)
pld := payload.CRCProposal{
- OwnerPublicKey: pk1Bytes,
- Recipient: *Recipient,
- Budgets: createBudgets(3),
+ OwnerKey: pk1Bytes,
+ Recipient: *Recipient,
+ Budgets: createBudgets(3),
}
propState := &crstate.ProposalState{
Status: crstate.VoterAgreed,
@@ -5252,7 +5278,7 @@ func (s *txValidatorTestSuite) TestCheckCRCProposalWithdrawTransaction() {
propState.ProposalOwner = pk2Bytes
err, _ = txn.SpecialContextCheck()
- s.EqualError(err, "transaction validate error: payload content invalid:the OwnerPublicKey is not owner of proposal")
+ s.EqualError(err, "transaction validate error: payload content invalid:the OwnerKey is not owner of proposal")
references[inputs[0]] = *outputs[1]
txn.SetReferences(references)
@@ -5354,8 +5380,8 @@ func (s *txValidatorTestSuite) getCRChangeProposalOwnerProposalTx(publicKeyStr,
crcProposalPayload := &payload.CRCProposal{
ProposalType: payload.ChangeProposalOwner,
- OwnerPublicKey: crPublicKey,
- NewOwnerPublicKey: newOwnerPublicKey,
+ OwnerKey: crPublicKey,
+ NewOwnerKey: newOwnerPublicKey,
TargetProposalHash: targetHash,
DraftHash: common.Hash(draftData),
CRCouncilMemberDID: *crDid,
@@ -5732,7 +5758,7 @@ func (s *txValidatorTestSuite) TestCheckCRCProposalTransaction() {
// invalid owner
txn = s.getCRCProposalTx(publicKeyStr2, privateKeyStr2, publicKeyStr1, privateKeyStr1)
- txn.Payload().(*payload.CRCProposal).OwnerPublicKey = []byte{}
+ txn.Payload().(*payload.CRCProposal).OwnerKey = []byte{}
txn = CreateTransactionByType(txn, s.Chain)
txn.SetParameters(&transaction.TransactionParameters{
Transaction: txn,
@@ -5748,7 +5774,7 @@ func (s *txValidatorTestSuite) TestCheckCRCProposalTransaction() {
// invalid owner signature
txn = s.getCRCProposalTx(publicKeyStr2, privateKeyStr2, publicKeyStr1, privateKeyStr1)
publicKey1, _ := common.HexStringToBytes(publicKeyStr1)
- txn.Payload().(*payload.CRCProposal).OwnerPublicKey = publicKey1
+ txn.Payload().(*payload.CRCProposal).OwnerKey = publicKey1
txn = CreateTransactionByType(txn, s.Chain)
txn.SetParameters(&transaction.TransactionParameters{
Transaction: txn,
@@ -5804,7 +5830,7 @@ func (s *txValidatorTestSuite) TestCheckCRCProposalTransaction() {
proposalState2, proposal2 := s.createSpecificStatusProposal(publicKey1, publicKey2, tenureHeight+1,
crstate.VoterAgreed, payload.ChangeProposalOwner)
proposal2.TargetProposalHash = targetHash
- proposal2.OwnerPublicKey = newOwnerPublicKey
+ proposal2.OwnerKey = newOwnerPublicKey
s.Chain.GetCRCommittee().GetProposalManager().Proposals[targetHash] = proposalState2
txn = s.getCRChangeProposalOwnerProposalTx(publicKeyStr2, privateKeyStr2, publicKeyStr1, privateKeyStr1,
newOwnerPublicKeyStr, targetHash)
@@ -6019,10 +6045,10 @@ func (s *txValidatorTestSuite) TestCheckReturnDepositCoinTransaction() {
common2.RegisterProducer,
0,
&payload.ProducerInfo{
- OwnerPublicKey: publicKey,
- NodePublicKey: publicKey,
- NickName: randomString(),
- Url: randomString(),
+ OwnerKey: publicKey,
+ NodePublicKey: publicKey,
+ NickName: randomString(),
+ Url: randomString(),
},
[]*common2.Attribute{},
[]*common2.Input{},
@@ -6092,7 +6118,7 @@ func (s *txValidatorTestSuite) TestCheckReturnDepositCoinTransaction() {
common2.CancelProducer,
0,
&payload.ProcessProducer{
- OwnerPublicKey: publicKey,
+ OwnerKey: publicKey,
},
[]*common2.Attribute{},
[]*common2.Input{},
@@ -7501,7 +7527,7 @@ func (s *txValidatorTestSuite) TestCreateCRClaimDposV2Transaction() {
})
err, _ = tx.SpecialContextCheck()
- s.EqualError(err.(errors.ELAError).InnerError(), "claim reward exceeded , max claim reward 0.00000100")
+ s.EqualError(err.(errors.ELAError).InnerError(), "claim reward exceeded , max claim reward 0.00000100current:0.00000100")
bc = s.Chain
bc.GetState().DPoSV2RewardInfo[stakeAddr] = 10000000000
@@ -7606,7 +7632,9 @@ func (s *txValidatorTestSuite) TestArbitersAccumulateReward() {
if err != nil {
fmt.Println("err", err)
}
-
+ ownerAddr, _ := getProgramHash(ownerPubKeyStr)
+ ownerAddr[0] = byte(contract.PrefixDPoSV2)
+ ownerStakeAddr, _ := ownerAddr.ToAddress()
type fields struct {
State *state.State
ChainParams *config.Configuration
@@ -7727,19 +7755,16 @@ func (s *txValidatorTestSuite) TestArbitersAccumulateReward() {
}
producer := &state.Producer{}
producer.SetInfo(payload.ProducerInfo{
- OwnerPublicKey: ownerPubKey,
- NodePublicKey: nodePubKey,
+ OwnerKey: ownerPubKey,
+ NodePublicKey: nodePubKey,
})
a.State.ActivityProducers[ownerPubKeyStr] = producer
//CurrentCRCArbitersMap
a.AccumulateReward(tt.args.block, tt.args.confirm)
a.History.Commit(tt.args.block.Height)
- addr, _ := common.Uint168FromAddress("ET54cpnGG4JHeRatvPij6hGV6zN18eVSSj")
- addr[0] = byte(contract.PrefixDPoSV2)
- stakeAddr, _ := addr.ToAddress()
- if a.State.DPoSV2RewardInfo[stakeAddr] != 102 {
+ if a.State.DPoSV2RewardInfo[ownerStakeAddr] != 102 {
t.Errorf("DPoSV2RewardInfo() addr %v, want %v, but %v",
- "ET54cpnGG4JHeRatvPij6hGV6zN18eVSSj", 102, a.State.DPoSV2RewardInfo)
+ "SYWG3rnjyfU6PKu1yjSqDLMHaxvn8d8nDn", 102, a.State.DPoSV2RewardInfo)
}
})
}
diff --git a/test/unit/validation_test.go b/test/unit/validation_test.go
index 09d9a1c1f..82b438c70 100644
--- a/test/unit/validation_test.go
+++ b/test/unit/validation_test.go
@@ -144,21 +144,21 @@ func TestCheckMultiSigSignature(t *testing.T) {
assert.NoError(t, err, "Generate signature failed, error %v", err)
// Normal
- err = blockchain.CheckMultiSigSignatures(program.Program{Code: act.redeemScript, Parameter: signature}, data)
+ err = crypto.CheckMultiSigSignatures(program.Program{Code: act.redeemScript, Parameter: signature}, data)
assert.NoError(t, err, "[CheckMultisigSignature] failed, %v", err)
// invalid redeem script M < 1
fakeCode := make([]byte, len(act.redeemScript))
copy(fakeCode, act.redeemScript)
fakeCode[0] = fakeCode[0] - fakeCode[0] + crypto.PUSH1 - 1
- err = blockchain.CheckMultiSigSignatures(program.Program{Code: fakeCode, Parameter: signature}, data)
+ err = crypto.CheckMultiSigSignatures(program.Program{Code: fakeCode, Parameter: signature}, data)
assert.Error(t, err, "[CheckMultisigSignature] code with M < 1 passed")
assert.Equal(t, "invalid multi sign script code", err.Error())
// invalid redeem script M > N
copy(fakeCode, act.redeemScript)
fakeCode[0] = fakeCode[len(fakeCode)-2] - crypto.PUSH1 + 2
- err = blockchain.CheckMultiSigSignatures(program.Program{Code: fakeCode, Parameter: signature}, data)
+ err = crypto.CheckMultiSigSignatures(program.Program{Code: fakeCode, Parameter: signature}, data)
assert.Error(t, err, "[CheckMultisigSignature] code with M > N passed")
assert.Equal(t, "invalid multi sign script code", err.Error())
@@ -167,7 +167,7 @@ func TestCheckMultiSigSignature(t *testing.T) {
for len(fakeCode) >= crypto.MinMultiSignCodeLength {
fakeCode = append(fakeCode[:1], fakeCode[crypto.PublicKeyScriptLength:]...)
}
- err = blockchain.CheckMultiSigSignatures(program.Program{Code: fakeCode, Parameter: signature}, data)
+ err = crypto.CheckMultiSigSignatures(program.Program{Code: fakeCode, Parameter: signature}, data)
assert.Error(t, err, "[CheckMultisigSignature] invalid length code passed")
assert.Equal(t, "not a valid multi sign transaction code, length not enough", err.Error())
@@ -175,7 +175,7 @@ func TestCheckMultiSigSignature(t *testing.T) {
fakeCode = make([]byte, len(act.redeemScript))
copy(fakeCode, act.redeemScript)
fakeCode[len(fakeCode)-2] = fakeCode[len(fakeCode)-2] + 1
- err = blockchain.CheckMultiSigSignatures(program.Program{Code: fakeCode, Parameter: signature}, data)
+ err = crypto.CheckMultiSigSignatures(program.Program{Code: fakeCode, Parameter: signature}, data)
assert.Error(t, err, "[CheckMultisigSignature] invalid redeem script N not equal to public keys count")
assert.Equal(t, "invalid multi sign public key script count", err.Error())
@@ -183,29 +183,29 @@ func TestCheckMultiSigSignature(t *testing.T) {
fakeCode = make([]byte, len(act.redeemScript))
copy(fakeCode, act.redeemScript)
fakeCode[2] = 0x01
- err = blockchain.CheckMultiSigSignatures(program.Program{Code: fakeCode, Parameter: signature}, data)
+ err = crypto.CheckMultiSigSignatures(program.Program{Code: fakeCode, Parameter: signature}, data)
assert.Error(t, err, "[CheckMultisigSignature] invalid redeem script wrong public key")
assert.Equal(t, "the encodeData format is error", err.Error())
// invalid signature length not match
- err = blockchain.CheckMultiSigSignatures(program.Program{Code: fakeCode, Parameter: signature[1+math.Intn(64):]}, data)
+ err = crypto.CheckMultiSigSignatures(program.Program{Code: fakeCode, Parameter: signature[1+math.Intn(64):]}, data)
assert.Error(t, err, "[CheckMultisigSignature] invalid signature length not match")
assert.Equal(t, "invalid multi sign signatures, length not match", err.Error())
// invalid signature not enough
cut := len(signature)/crypto.SignatureScriptLength - int(act.redeemScript[0]-crypto.PUSH1)
- err = blockchain.CheckMultiSigSignatures(program.Program{Code: act.redeemScript, Parameter: signature[65*cut:]}, data)
+ err = crypto.CheckMultiSigSignatures(program.Program{Code: act.redeemScript, Parameter: signature[65*cut:]}, data)
assert.Error(t, err, "[CheckMultisigSignature] invalid signature not enough")
assert.Equal(t, "invalid signatures, not enough signatures", err.Error())
// invalid signature too many
- err = blockchain.CheckMultiSigSignatures(program.Program{Code: act.redeemScript,
+ err = crypto.CheckMultiSigSignatures(program.Program{Code: act.redeemScript,
Parameter: append(signature[:65], signature...)}, data)
assert.Error(t, err, "[CheckMultisigSignature] invalid signature too many")
assert.Equal(t, "invalid signatures, too many signatures", err.Error())
// invalid signature duplicate
- err = blockchain.CheckMultiSigSignatures(program.Program{Code: act.redeemScript,
+ err = crypto.CheckMultiSigSignatures(program.Program{Code: act.redeemScript,
Parameter: append(signature[:65], signature[:len(signature)-65]...)}, data)
assert.Error(t, err, "[CheckMultisigSignature] invalid signature duplicate")
assert.Equal(t, "duplicated signatures", err.Error())
@@ -213,7 +213,7 @@ func TestCheckMultiSigSignature(t *testing.T) {
// invalid signature fake signature
signature, err = newMultiAccount(math.Intn(2)+3, t).Sign(data)
assert.NoError(t, err, "Generate signature failed, error %v", err)
- err = blockchain.CheckMultiSigSignatures(program.Program{Code: act.redeemScript, Parameter: signature}, data)
+ err = crypto.CheckMultiSigSignatures(program.Program{Code: act.redeemScript, Parameter: signature}, data)
assert.Error(t, err, "[CheckMultisigSignature] invalid signature fake signature")
}
diff --git a/utils/history.go b/utils/history.go
index 99c9c75ad..9dfe6dd4c 100644
--- a/utils/history.go
+++ b/utils/history.go
@@ -132,9 +132,25 @@ func (h *History) Commit(height uint32) {
h.changes[i].commit()
}
+ // same height changes is just one
+ holdHeight := make(map[uint32]bool, 0)
+ var lastHeight uint32
+ lastHeightChangesCount := 0
+ for i, change := range h.changes {
+ if i == 0 {
+ lastHeight = change.height
+ }
+ if change.height == lastHeight {
+ lastHeightChangesCount++
+ }
+ _, ok := holdHeight[change.height]
+ if !ok {
+ holdHeight[change.height] = true
+ }
+ }
// if changes overflows history's capacity, remove the oldest change.
- if len(h.changes) >= h.capacity {
- h.changes = h.changes[1:]
+ if len(holdHeight) >= h.capacity {
+ h.changes = h.changes[lastHeightChangesCount:]
}
// if no cached changes, create an empty height change.
diff --git a/wallet/coincheckpoint.go b/wallet/coincheckpoint.go
index f09565362..e3a5bd30e 100644
--- a/wallet/coincheckpoint.go
+++ b/wallet/coincheckpoint.go
@@ -28,6 +28,10 @@ type CoinsCheckPoint struct {
sync.RWMutex
}
+func (c *CoinsCheckPoint) SaveStartHeight() uint32 {
+ return 0
+}
+
func (ccp *CoinsCheckPoint) StartHeight() uint32 {
return 0
}