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 f031b6d16..1a7438cc5 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 5fe7ff1b8..5df73e5a3 100644 --- a/blockchain/blockvalidator.go +++ b/blockchain/blockvalidator.go @@ -159,7 +159,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") @@ -178,7 +178,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") @@ -197,7 +197,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") diff --git a/blockchain/indexers/checkpoint.go b/blockchain/indexers/checkpoint.go index 10af8cfde..660708a2c 100644 --- a/blockchain/indexers/checkpoint.go +++ b/blockchain/indexers/checkpoint.go @@ -91,6 +91,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/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 a3f545051..4b6327395 100644 --- a/common/config/config.go +++ b/common/config/config.go @@ -194,6 +194,8 @@ func GetDefaultParams() *Configuration { CandidatesCount: 72, DPoSV2RewardAccumulateProgramHash: StakeRewardProgramHash, NFTStartHeight: 1405000, + NFTV2StartHeight: math.MaxUint32, // todo complete me + DexStartHeight: math.MaxUint32, // todo complete me OriginArbiters: []string{ "0248df6705a909432be041e0baa25b8f648741018f70d1911f2ed28778db4b8fe4", "02771faf0f4d4235744b30972d5f2c470993920846c761e4d08889ecfdc061cddf", @@ -254,6 +256,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, @@ -352,7 +356,7 @@ 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 @@ -368,6 +372,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 @@ -380,6 +385,8 @@ func (p *Configuration) TestNet() *Configuration { p.CrossChainMonitorInterval = 100 p.CRConfiguration.CRClaimPeriod = 10080 p.DPoSConfiguration.NFTStartHeight = 1098000 + p.DPoSConfiguration.NFTV2StartHeight = math.MaxUint32 // todo complete me + p.DPoSConfiguration.DexStartHeight = math.MaxUint32 // todo complete me p.HttpInfoPort = 21333 p.HttpRestPort = 21334 @@ -388,6 +395,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 @@ -472,7 +480,7 @@ 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 @@ -488,6 +496,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 @@ -500,6 +509,7 @@ func (p *Configuration) RegNet() *Configuration { p.CrossChainMonitorInterval = 100 p.CRConfiguration.CRClaimPeriod = 10080 p.DPoSConfiguration.NFTStartHeight = 968000 + p.DPoSConfiguration.NFTV2StartHeight = math.MaxUint32 // todo complete me p.HttpInfoPort = 22333 p.HttpRestPort = 22334 p.HttpWsPort = 22335 @@ -507,6 +517,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 @@ -623,6 +635,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 @@ -640,6 +654,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 @@ -720,6 +736,10 @@ type DPoSConfiguration struct { CRDPoSNodeHotFixHeight uint32 `screw:"--crdposnodehotfixheight" usage:"CRDPoSNodeHotFixHeight indicates the hot fix start height of CR DPoS node"` // NFTStartHeight defines the height of NFT started. NFTStartHeight uint32 `screw:"--nftstartheight" usage:"the start height of NFT transaction"` + // 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 { diff --git a/core/checkpoint/manager.go b/core/checkpoint/manager.go index 4facf3146..d35087bd7 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 @@ -305,8 +308,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) { @@ -316,7 +317,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 } @@ -327,30 +329,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 { @@ -358,21 +348,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 7fe614705..28a979599 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 dde5c0547..1f583fc12 100644 --- a/core/transaction/dposv2claimrewardtransaction.go +++ b/core/transaction/dposv2claimrewardtransaction.go @@ -104,7 +104,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 { @@ -148,7 +148,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/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/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 a62a919c5..39a92f6d8 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. @@ -145,6 +145,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/dpos/arbitrator.go b/dpos/arbitrator.go index f4b42b4af..0ea75a272 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()), diff --git a/dpos/manager/dposmanager.go b/dpos/manager/dposmanager.go index ce020f9f3..b5ae03b92 100644 --- a/dpos/manager/dposmanager.go +++ b/dpos/manager/dposmanager.go @@ -658,14 +658,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) } diff --git a/dpos/manager/dposondutyhandler.go b/dpos/manager/dposondutyhandler.go index 4377cd3e6..aaf729b85 100644 --- a/dpos/manager/dposondutyhandler.go +++ b/dpos/manager/dposondutyhandler.go @@ -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/proposaldispatcher.go b/dpos/manager/proposaldispatcher.go index 8b700b9bc..77e4ed50a 100644 --- a/dpos/manager/proposaldispatcher.go +++ b/dpos/manager/proposaldispatcher.go @@ -513,6 +513,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 +523,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 +612,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 +621,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 +642,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) } @@ -715,13 +729,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 } diff --git a/dpos/state/arbitrators.go b/dpos/state/arbitrators.go index cae18b880..3a69ca0f0 100644 --- a/dpos/state/arbitrators.go +++ b/dpos/state/arbitrators.go @@ -27,6 +27,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" @@ -122,6 +123,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() @@ -510,6 +520,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) @@ -519,6 +536,7 @@ func (a *Arbiters) notifyNextTurnDPOSInfoTx(blockHeight, versionHeight uint32, f nextTurnDPOSInfoTx := a.createNextTurnDPOSInfoTransactionV0(blockHeight, forceChange) go events.Notify(events.ETAppendTxToTxPool, nextTurnDPOSInfoTx) + return } @@ -703,7 +721,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() @@ -722,7 +740,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() @@ -945,7 +963,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()) } @@ -958,7 +976,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 { @@ -1031,7 +1049,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 { @@ -1092,7 +1110,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 { @@ -1862,6 +1880,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 @@ -1978,7 +2046,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 @@ -2009,7 +2077,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]...) @@ -2048,7 +2116,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) @@ -2179,7 +2247,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 @@ -2195,7 +2263,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() { @@ -2327,8 +2395,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, } @@ -2566,7 +2634,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) @@ -2612,8 +2680,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 } @@ -2652,7 +2719,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 } @@ -2877,8 +2944,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 28b7c99fc..04a4b6133 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 @@ -59,6 +59,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 eda9cdd89..d7e4cc05f 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 ae2433113..fbfc93834 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 @@ -1301,6 +1302,14 @@ func (s *State) ProcessBlock(block *types.Block, confirm *payload.Confirm, dutyI } } + // 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) @@ -1310,14 +1319,6 @@ func (s *State) ProcessBlock(block *types.Block, confirm *payload.Confirm, dutyI 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) { @@ -1697,7 +1698,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) @@ -1832,16 +1833,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) @@ -1901,7 +1920,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() { @@ -1927,8 +1946,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 @@ -2401,13 +2420,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..68bcae1ea 100644 --- a/go.mod +++ b/go.mod @@ -1,15 +1,14 @@ 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.22.3 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 @@ -19,5 +18,41 @@ require ( github.com/yuin/gopher-lua v0.0.0-20210529063254-f4c35e4016d9 golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4 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.0-20180518054509-2e65f85255db // 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.0.0-20220722155257-8c9f86f7a55f // indirect + golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 // indirect + golang.org/x/text v0.3.8 // 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 7ee727415..db0a5c67a 100644 --- a/mempool/txpool.go +++ b/mempool/txpool.go @@ -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 868fb136c..d8e4a422c 100644 --- a/mempool/txpoolcheckpoint.go +++ b/mempool/txpoolcheckpoint.go @@ -118,6 +118,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..778ce99bd 100644 --- a/pow/revertlistener.go +++ b/pow/revertlistener.go @@ -29,7 +29,7 @@ func (pow *Service) ListenForRevert() { } lastBlockTimestamp := int64(pow.arbiters.GetLastBlockTimestamp()) localTimestamp := pow.chain.TimeSource.AdjustedTime().Unix() - log.Info("ListenForRevert lastBlockTimestamp:", lastBlockTimestamp, + log.Debug("ListenForRevert lastBlockTimestamp:", lastBlockTimestamp, "localTimestamp:", localTimestamp, "RevertToPOWNoBlockTime:", pow.chainParams.DPoSConfiguration.RevertToPOWNoBlockTime) if localTimestamp-lastBlockTimestamp < pow.chainParams.DPoSConfiguration.RevertToPOWNoBlockTime { 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..b1d9017fd 100644 --- a/test/unit/dposkeyframe_test.go +++ b/test/unit/dposkeyframe_test.go @@ -426,7 +426,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 +488,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 e63ae5ff3..648fb6cc7 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 @@ -1130,8 +1130,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 @@ -1210,8 +1210,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 @@ -1276,7 +1276,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 @@ -1305,8 +1305,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 @@ -1407,9 +1407,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{}, @@ -1492,7 +1492,7 @@ func TestDPoSState_ProcessBlock_DepositAndReturnDeposit(t *testing.T) { common2.CancelProducer, 0, &payload.ProcessProducer{ - OwnerPublicKey: pkBuf, + OwnerKey: pkBuf, }, []*common2.Attribute{}, []*common2.Input{}, @@ -1559,8 +1559,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) @@ -1603,7 +1603,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. @@ -1623,7 +1623,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 332331851..c54cca6ca 100644 --- a/test/unit/txvalidator_test.go +++ b/test/unit/txvalidator_test.go @@ -72,6 +72,8 @@ func (s *txValidatorTestSuite) SetupSuite() { params := &config.DefaultParams params.DPoSV2StartHeight = 0 + params.GenesisBlock = core.GenesisBlock(*params.FoundationProgramHash) + blockchain.FoundationAddress = *params.FoundationProgramHash s.foundationAddress = *params.FoundationProgramHash @@ -872,12 +874,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) @@ -913,7 +915,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") @@ -926,7 +928,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 @@ -937,20 +939,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) @@ -1009,13 +1011,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) @@ -1062,7 +1064,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") @@ -1071,12 +1073,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{ @@ -1086,7 +1088,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{}, @@ -1161,8 +1163,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, @@ -1178,6 +1184,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") @@ -1203,6 +1213,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") @@ -1228,6 +1242,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") @@ -1253,6 +1271,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") @@ -1280,6 +1302,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") @@ -1855,12 +1881,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 @@ -1898,39 +1924,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() @@ -1946,12 +1972,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() @@ -1962,12 +1988,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() @@ -1978,12 +2004,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() @@ -1994,12 +2020,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() @@ -2011,12 +2037,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() @@ -2027,12 +2053,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) @@ -2051,12 +2077,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) @@ -2074,12 +2100,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) @@ -2153,12 +2179,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), @@ -2209,12 +2235,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++ @@ -2226,7 +2252,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") @@ -2239,7 +2265,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 @@ -2250,18 +2276,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) @@ -2285,12 +2311,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), @@ -2342,13 +2368,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++ @@ -2360,7 +2386,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") @@ -2373,7 +2399,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 @@ -2384,18 +2410,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) @@ -2449,13 +2475,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), @@ -2507,13 +2533,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++ @@ -2525,7 +2551,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") @@ -2538,7 +2564,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 @@ -2549,18 +2575,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) @@ -2601,7 +2627,7 @@ func (s *txValidatorTestSuite) TestCheckCancelProducerTransaction() { errPublicKey, _ := common.HexStringToBytes(errPublicKeyStr) cancelPayload := &payload.ProcessProducer{ - OwnerPublicKey: publicKey1, + OwnerKey: publicKey1, } programs := []*program.Program{{ @@ -2621,17 +2647,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()) @@ -2654,12 +2680,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), @@ -2715,13 +2741,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), @@ -2777,12 +2803,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), @@ -2844,13 +2870,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) @@ -2952,12 +2978,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), @@ -3033,13 +3059,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), @@ -3647,7 +3673,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, @@ -3704,7 +3730,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), @@ -3738,7 +3764,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), @@ -3766,7 +3792,7 @@ func (s *txValidatorTestSuite) createSpecificStatusProposal(publicKey1, publicKe FinalPaymentStatus: false, TrackingCount: 0, TerminatedHeight: 0, - ProposalOwner: proposal.OwnerPublicKey, + ProposalOwner: proposal.OwnerKey, } return proposalState, proposal } @@ -3798,7 +3824,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, @@ -3845,7 +3871,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{ @@ -3903,7 +3929,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)), @@ -3966,7 +3992,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, @@ -4018,7 +4044,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)}, @@ -4067,7 +4093,7 @@ func (s *txValidatorTestSuite) TestCheckCRCProposalTrackingTransaction() { pld := payload.CRCProposal{ ProposalType: 0, - OwnerPublicKey: ownerPubKey, + OwnerKey: ownerPubKey, CRCouncilMemberDID: *randomUint168(), DraftHash: *randomUint256(), Budgets: createBudgets(3), @@ -4117,7 +4143,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, @@ -4146,7 +4172,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, @@ -4189,7 +4215,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, @@ -4256,7 +4282,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), @@ -4284,7 +4310,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), @@ -4345,8 +4371,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), } @@ -5072,15 +5098,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) } @@ -5164,9 +5190,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, @@ -5251,7 +5277,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) @@ -5353,8 +5379,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, @@ -5731,7 +5757,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, @@ -5747,7 +5773,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, @@ -5803,7 +5829,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) @@ -6018,10 +6044,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{}, @@ -6091,7 +6117,7 @@ func (s *txValidatorTestSuite) TestCheckReturnDepositCoinTransaction() { common2.CancelProducer, 0, &payload.ProcessProducer{ - OwnerPublicKey: publicKey, + OwnerKey: publicKey, }, []*common2.Attribute{}, []*common2.Input{}, @@ -7500,7 +7526,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 @@ -7721,8 +7747,8 @@ func (s *txValidatorTestSuite) TestArbitersAccumulateReward() { } producer := &state.Producer{} producer.SetInfo(payload.ProducerInfo{ - OwnerPublicKey: nodePubKey, - NodePublicKey: nodePubKey, + OwnerKey: nodePubKey, + NodePublicKey: nodePubKey, }) a.State.ActivityProducers[ownerPubKeyStr] = producer //CurrentCRCArbitersMap 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/wallet/coincheckpoint.go b/wallet/coincheckpoint.go index e328d4e74..745039a3f 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 }