diff --git a/models/blockchain.go b/models/blockchain.go index 122f3b218..bd0bd95b9 100755 --- a/models/blockchain.go +++ b/models/blockchain.go @@ -9,7 +9,7 @@ import ( type BlockChainCommitStatus int const ( BlockChainCommitInit BlockChainCommitStatus = iota - BlockChainCommitReady + BlockChainCommitSuccess BlockChainCommitFailed ) type BlockChain struct { @@ -21,6 +21,7 @@ type BlockChain struct { Amount int64 `xorm:"INDEX"` UserID int64 `xorm:"INDEX"` RepoID int64 `xorm:"INDEX"` + TransactionHash string `xorm:"INDEX"` CreatedUnix timeutil.TimeStamp `xorm:"created"` UpdatedUnix timeutil.TimeStamp `xorm:"updated"` DeletedAt time.Time `xorm:"deleted"` @@ -68,3 +69,9 @@ func UpdateBlockChainCols(blockChain *BlockChain, cols ...string) error { return updateBlockChainCols(x, blockChain, cols...) } +func GetBlockChainUnSuccessCommits() ([]*BlockChain, error) { + blockChains := make([]*BlockChain, 0, 10) + return blockChains, x. + Where("status != ?", BlockChainCommitSuccess). + Find(&blockChains) +} diff --git a/models/repo.go b/models/repo.go index d21b8ae80..7cda4ce8a 100755 --- a/models/repo.go +++ b/models/repo.go @@ -145,7 +145,7 @@ const ( const ( RepoBlockChainInit RepoBlockChainStatus = iota - RepoBlockChainReady + RepoBlockChainSuccess RepoBlockChainFailed ) @@ -2406,3 +2406,10 @@ func updateRepositoryCols(e Engine, repo *Repository, cols ...string) error { func UpdateRepositoryCols(repo *Repository, cols ...string) error { return updateRepositoryCols(x, repo, cols...) } + +func GetBlockChainUnSuccessRepos() ([]*Repository, error) { + repos := make([]*Repository, 0, 10) + return repos, x. + Where("block_chain_status != ?", RepoBlockChainSuccess). + Find(&repos) +} diff --git a/models/user.go b/models/user.go index 468d42822..2b1195179 100755 --- a/models/user.go +++ b/models/user.go @@ -175,6 +175,7 @@ type User struct { //BlockChain PublicKey string `xorm` + PrivateKey string `xorm` } // SearchOrganizationsOptions options to filter organizations @@ -979,6 +980,7 @@ func CreateUser(u *User) (err error) { } u.PublicKey = result.Payload["publickey"].(string) + u.PrivateKey = result.Payload["privatekey"].(string) sess := x.NewSession() defer sess.Close() @@ -2040,3 +2042,11 @@ func SyncExternalUsers(ctx context.Context, updateExisting bool) error { } return nil } + +func GetBlockChainUnSuccessUsers() ([]*User, error) { + users := make([]*User, 0, 10) + err := x.Where("public_key is null"). + Or("private_key is null"). + Find(&users) + return users, err +} diff --git a/modules/blockchain/resty.go b/modules/blockchain/resty.go index 0f288b91a..060d63144 100755 --- a/modules/blockchain/resty.go +++ b/modules/blockchain/resty.go @@ -17,6 +17,8 @@ const ( UrlNewRepo = "newRepo" UrlContribute = "contribute" + ActionCommit = "commit" + Success = 0 ) @@ -35,7 +37,7 @@ type GetBalanceResult struct { type NewRepoResult struct { Code int `json:"code"` Msg string `json:"message"` - Data string `json:"data"` + //Data string `json:"data"` } type ContributeResult struct { diff --git a/modules/timer/timer.go b/modules/timer/timer.go index d0a850bca..3de4ee49c 100755 --- a/modules/timer/timer.go +++ b/modules/timer/timer.go @@ -10,5 +10,11 @@ func init() { c := cron.New() spec := "*/10 * * * *" c.AddFunc(spec, repo.HandleUnDecompressAttachment) + specCheckBlockChainUserSuccess := "*/10 * * * *" + c.AddFunc(specCheckBlockChainUserSuccess, repo.HandleBlockChainUnSuccessUsers) + specCheckRepoBlockChainSuccess := "*/5 * * * *" + c.AddFunc(specCheckRepoBlockChainSuccess, repo.HandleBlockChainUnSuccessRepos) + specCheckBlockChainCommitSuccess := "*/3 * * * *" + c.AddFunc(specCheckBlockChainCommitSuccess, repo.HandleBlockChainUnSuccessCommits) c.Start() } diff --git a/routers/repo/blockchain.go b/routers/repo/blockchain.go index 293167d2f..1fa376fd8 100755 --- a/routers/repo/blockchain.go +++ b/routers/repo/blockchain.go @@ -2,8 +2,10 @@ package repo import ( "encoding/json" + "strconv" "code.gitea.io/gitea/models" + "code.gitea.io/gitea/modules/blockchain" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" ) @@ -15,6 +17,7 @@ type BlockChainInitNotify struct { type BlockChainCommitNotify struct { CommitID string `json:"commitId"` + TransactionHash string `json:"txHash"` } func HandleBlockChainInitNotify(ctx *context.Context) { @@ -26,76 +29,152 @@ func HandleBlockChainInitNotify(ctx *context.Context) { if err != nil { log.Error("GetRepositoryByID failed:", err.Error()) ctx.JSON(200, map[string]string{ - "result_code" : "-1", + "code" : "-1", "message" : "internal error", }) return } - if repo.BlockChainStatus == models.RepoBlockChainReady && len(repo.ContractAddress) != 0 { - log.Error("the repo has been RepoBlockChainReady:", req.RepoId) + if repo.BlockChainStatus == models.RepoBlockChainSuccess && len(repo.ContractAddress) != 0 { + log.Error("the repo has been RepoBlockChainSuccess:", req.RepoId) ctx.JSON(200, map[string]string{ - "result_code" : "-1", - "message" : "the repo has been RepoBlockChainReady", + "code" : "-1", + "message" : "the repo has been RepoBlockChainSuccess", }) return } - repo.BlockChainStatus = models.RepoBlockChainReady + repo.BlockChainStatus = models.RepoBlockChainSuccess repo.ContractAddress = req.ContractAddress if err = models.UpdateRepositoryCols(repo, "block_chain_status", "contract_address"); err != nil { log.Error("UpdateRepositoryCols failed:", err.Error()) ctx.JSON(200, map[string]string{ - "result_code" : "-1", + "code" : "-1", "message" : "internal error", }) return } ctx.JSON(200, map[string]string{ - "result_code": "0", + "code": "0", + "message": "", }) } func HandleBlockChainCommitNotify(ctx *context.Context) { - //contributor := ctx.Query("contributor") - //contractAddress := ctx.Query("contractAddress") var req BlockChainCommitNotify data, _ := ctx.Req.Body().Bytes() - json.Unmarshal(data, &req) + if err := json.Unmarshal(data, &req); err != nil { + log.Error("json.Unmarshal failed:", err.Error()) + ctx.JSON(200, map[string]string{ + "code" : "-1", + "message" : "response data error", + }) + return + } blockChain, err := models.GetBlockChainByCommitID(req.CommitID) if err != nil { log.Error("GetRepositoryByID failed:", err.Error()) ctx.JSON(200, map[string]string{ - "result_code" : "-1", + "code" : "-1", "message" : "internal error", }) return } - if blockChain.Status == models.BlockChainCommitReady { + if blockChain.Status == models.BlockChainCommitSuccess { log.Error("the commit has been BlockChainCommitReady:", blockChain.RepoID) ctx.JSON(200, map[string]string{ - "result_code" : "-1", + "code" : "-1", "message" : "the commit has been BlockChainCommitReady", }) return } - blockChain.Status = models.BlockChainCommitReady + blockChain.Status = models.BlockChainCommitSuccess + blockChain.TransactionHash = req.TransactionHash - if err = models.UpdateBlockChainCols(blockChain, "status"); err != nil { + if err = models.UpdateBlockChainCols(blockChain, "status", "transaction_hash"); err != nil { log.Error("UpdateBlockChainCols failed:", err.Error()) ctx.JSON(200, map[string]string{ - "result_code" : "-1", + "code" : "-1", "message" : "internal error", }) return } ctx.JSON(200, map[string]string{ - "result_code": "0", + "code": "0", + "message": "", }) } + +func HandleBlockChainUnSuccessRepos() { + repos, err := models.GetBlockChainUnSuccessRepos() + if err != nil { + log.Error("GetBlockChainUnSuccessRepos failed:", err.Error()) + return + } + + for _, repo := range repos { + err = repo.GetOwner() + if err != nil { + log.Error("GetOwner(%s) failed:%s", repo.Name, err.Error()) + continue + } + if len(repo.Owner.PrivateKey) == 0 || len(repo.Owner.PublicKey) == 0 { + log.Error("the user has not been init in block_chain:", repo.Owner.Name) + continue + } + strRepoID := strconv.FormatInt(repo.ID, 10) + log.Info(strRepoID) + _, err = blockchain.NewRepo(strRepoID, repo.Owner.PublicKey, repo.Name) + if err != nil { + log.Error("blockchain.NewRepo(%s) failed:%s", strRepoID, err.Error()) + } + } + + return +} + +func HandleBlockChainUnSuccessCommits() { + blockChains, err := models.GetBlockChainUnSuccessCommits() + if err != nil { + log.Error("GetBlockChainUnSuccessCommits failed:", err.Error()) + return + } + + for _, block_chain := range blockChains { + _, err = blockchain.Contribute(block_chain.ContractAddress, block_chain.Contributor, blockchain.ActionCommit, block_chain.CommitID, int(block_chain.Amount)) + if err != nil { + log.Error("blockchain.Contribute(%s) failed:%s", block_chain.CommitID, err.Error()) + } + } + + return +} + +func HandleBlockChainUnSuccessUsers() { + users, err := models.GetBlockChainUnSuccessUsers() + if err != nil { + log.Error("GetBlockChainUnSuccessUsers failed:", err.Error()) + return + } + + for _, user := range users { + result, err := blockchain.CreateBlockchainAccount() + if err != nil { + log.Error("blockchain.CreateBlockchainAccount(%s) failed:%s", user.Name, err.Error()) + continue + } + + user.PublicKey = result.Payload["publickey"].(string) + user.PrivateKey = result.Payload["privatekey"].(string) + + models.UpdateUser(user) + } + + return +}