Chain.go
package main
import (
"fmt"
"os"
"path/filepath"
"strconv"
"strings"
"time"
)
const (
ConfirmInterval = 600
ResourceConfirmCount = 10
ValidatorCount = 5
GenesisAddress = "genesis_address"
)
var Config = struct {
ChainInfoPath string
}{
ChainInfoPath: "./chain_info.txt",
}
type File struct{}
func (f *File) Read(filename string) string {
content, err := os.ReadFile(filename)
if err != nil {
return ""
}
return strings.TrimSpace(string(content))
}
func (f *File) Overwrite(filename string, data interface{}) {
content := fmt.Sprintf("%v", data)
os.WriteFile(filename, []byte(content), 0644)
}
func (f *File) MakeDirectory(path string) error {
return os.MkdirAll(path, os.ModePerm)
}
type Clock struct{}
func (c *Clock) Ufloortime() int64 {
return time.Now().Unix()
}
type Signer struct{}
func (s *Signer) AddressValidity(address string) bool {
// 실제 주소 유효성 검사 로직 구현
return true
}
type Logger struct{}
func (l *Logger) Log(message string) {
fmt.Println(message)
}
type MainBlock struct {
BlockHash string
STimestamp int64
}
type ResourceBlock struct {
MainHeight int
BlockHash string
Validator string
Miner string
}
type MainChain struct{}
func (mc *MainChain) Instance() *MainChain {
return &MainChain{}
}
func (mc *MainChain) Block(height int) *MainBlock {
// 실제 블록 조회 로직 구현
return &MainBlock{
BlockHash: "blockhash",
STimestamp: 1633036800,
}
}
type ResourceChain struct{}
func (rc *ResourceChain) Instance() *ResourceChain {
return &ResourceChain{}
}
func (rc *ResourceChain) LastHeight() int {
// 실제 마지막 높이 조회 로직 구현
return 100
}
func (rc *ResourceChain) LastBlock() *ResourceBlock {
// 실제 마지막 블록 조회 로직 구현
return &ResourceBlock{
MainHeight: 100,
BlockHash: "lastblockhash",
Validator: "validator",
Miner: "miner",
}
}
func (rc *ResourceChain) Block(height int) *ResourceBlock {
// 실제 블록 조회 로직 구현
return &ResourceBlock{
MainHeight: height,
BlockHash: "blockhash",
Validator: "validator",
Miner: "miner",
}
}
func (rc *ResourceChain) BeforeBlock(timestamp int) *ResourceBlock {
// 실제 이전 블록 조회 로직 구현
return &ResourceBlock{
MainHeight: 100,
BlockHash: "blockhash",
Validator: "validator",
Miner: "miner",
}
}
type Status struct{}
func (s *Status) Instance() *Status {
return &Status{}
}
func (s *Status) Cache() {
// 캐시 로직 구현
}
func (s *Status) BundleHeight() int {
// 번들 높이 조회 로직 구현
return 100
}
func (s *Status) Write(block *MainBlock) {
// 블록 기록 로직 구현
}
type Chain struct{}
func (c *Chain) Reset() {
c.SetFixedHeight(0)
}
func (c *Chain) FixedHeight() int {
height, _ := strconv.Atoi(File{}.Read(Config.ChainInfoPath))
return height
}
func (c *Chain) FixedPoint(timestamp int) int {
lastHeight := ResourceChain{}.Instance().LastHeight()
if lastHeight > 0 {
confirmedHeight := c.ConfirmedHeight(timestamp)
fixLimit := max(lastHeight-10, 1)
return min(confirmedHeight, fixLimit)
}
return 0
}
func (c *Chain) UpdateFixedHeight() {
fixedPoint := c.FixedPoint(Clock{}.Ufloortime())
fixedHeight := c.FixedHeight()
if fixedHeight < fixedPoint {
targetBlock := ResourceChain{}.Instance().Block(fixedPoint)
mainBlock := MainChain{}.Instance().Block(targetBlock.MainHeight)
if targetBlock.BlockHash == mainBlock.BlockHash {
c.SetFixedHeight(fixedPoint)
}
}
}
func (c *Chain) SetFixedHeight(height int) {
File{}.Overwrite(Config.ChainInfoPath, height)
}
func (c *Chain) FixedResourceBlock() *ResourceBlock {
return ResourceChain{}.Instance().Block(c.FixedHeight())
}
func (c *Chain) FixedMainHeight() int {
resourceBlock := c.FixedResourceBlock()
return resourceBlock.MainHeight
}
func (c *Chain) ConfirmedHeight(timestamp int) int {
return c.ConfirmedResourceBlock(timestamp).MainHeight
}
func (c *Chain) ConfirmedResourceBlock(timestamp int) *ResourceBlock {
confirmedTimestamp := max(timestamp-ConfirmInterval, 0)
return ResourceChain{}.Instance().BeforeBlock(confirmedTimestamp)
}
func (c *Chain) ConfirmedMainBlock(timestamp int) *MainBlock {
resourceBlock := c.ConfirmedResourceBlock(timestamp)
return MainChain{}.Instance().Block(resourceBlock.MainHeight)
}
func (c *Chain) SelectValidators(confirmedHeight int) []string {
if confirmedHeight <= ResourceConfirmCount {
return []string{GenesisAddress}
}
if confirmedHeight == ResourceChain{}.Instance().LastBlock().MainHeight {
return []string{}
}
var validators []string
startHeight := max(confirmedHeight-ValidatorCount+1, 1)
for i := startHeight; i <= confirmedHeight; i++ {
block := ResourceChain{}.Instance().Block(i)
if Signer{}.AddressValidity(block.Validator) {
validators = append(validators, block.Validator)
}
}
return validators
}
func (c *Chain) SelectMiners(confirmedHeight int) []string {
if confirmedHeight <= ResourceConfirmCount {
return []string{GenesisAddress}
}
if confirmedHeight == ResourceChain{}.Instance().LastBlock().MainHeight {
return []string{}
}
var miners []string
startHeight := max(confirmedHeight-ValidatorCount+1, 1)
for i := startHeight; i <= confirmedHeight; i++ {
block := ResourceChain{}.Instance().Block(i)
if Signer{}.AddressValidity(block.Miner) {
miners = append(miners, block.Miner)
}
}
return miners
}
func (c *Chain) Bundling(once bool) {
Status{}.Instance().Cache()
fixedHeight := c.FixedMainHeight()
bundleHeight := Status{}.Instance().BundleHeight()
for i := bundleHeight + 1; i <= fixedHeight; i++ {
Status{}.Instance().Write(MainChain{}.Instance().Block(i))
if i%256 == 0 || i == fixedHeight {
Logger{}.Log(fmt.Sprintf("Commit Bundle: %d", i))
if once {
break
}
}
}
}
func max(a, b int) int {
if a > b {
return a
}
return b
}
func min(a, b int) int {
if a < b {
return a
}
return b
}
func main() {
chain := &Chain{}
chain.Reset()
fmt.Println("Fixed Height:", chain.FixedHeight())
chain.UpdateFixedHeight()
fmt.Println("Updated Fixed Height:", chain.FixedHeight())
}주요 구성 요소와 함수
보조 함수
main 함수
요약
Last updated