Skip to content

Commit

Permalink
Fix consensus issues
Browse files Browse the repository at this point in the history
  • Loading branch information
pouya-eghbali committed Mar 12, 2024
1 parent 3bf1f15 commit b971402
Show file tree
Hide file tree
Showing 7 changed files with 121 additions and 83 deletions.
2 changes: 1 addition & 1 deletion src/address/address.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (
"github.com/KenshiTech/unchained/crypto/shake"
)

var chars = "0123456789ABCDEFGHJKMNPQTSTUVXYZ"
var chars = "0123456789ABCDEFGHJKMNPQRSTUVXYZ"

func ToBase32(input []byte) string {
var output []byte
Expand Down
5 changes: 3 additions & 2 deletions src/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,12 @@ func defaults() {
Config.SetDefault("name", petname.Generate(3, "-"))
Config.SetDefault("log", "info")
Config.SetDefault("rpc.ethereum", "https://ethereum.publicnode.com")
Config.SetDefault("rpc.arbitrum_sepolia", "https://sepolia-rollup.arbitrum.io/rpc")
Config.SetDefault("broker.bind", "0.0.0.0:9123")
Config.SetDefault("pos.chain", "arbitrum_sepolia")
Config.SetDefault("pos.address", "0x08cE842914b7313E16DBA708ccF0418bE3dE05c6")
Config.SetDefault("pos.address", "0xdA36f22C0Dab89CA0884489Bf3a00c0C27cEDbec")
Config.SetDefault("pos.base", "1")
Config.SetDefault("pos.nft", "25000000000000000000000")
Config.SetDefault("pos.nft", "40000000000000000000000")
}

var Config *viper.Viper
Expand Down
2 changes: 1 addition & 1 deletion src/constants/constants.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package constants

var Version = "0.11.18"
var Version = "0.11.19"
var ProtocolVersion = "0.11.17"
39 changes: 17 additions & 22 deletions src/plugins/logs/logs.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"sync"
"time"

"github.com/KenshiTech/unchained/address"
"github.com/KenshiTech/unchained/config"
"github.com/KenshiTech/unchained/constants/opcodes"
"github.com/KenshiTech/unchained/crypto/bls"
Expand Down Expand Up @@ -111,13 +112,14 @@ func RecordSignature(
return
}

if !historical {
// TODO: Standalone mode shouldn't call this or check consensus
blockNumber, err := GetBlockNumber(info.Chain)

blockNumber, err := GetBlockNumber(info.Chain)
if err != nil {
panic(err)
}

if err != nil {
panic(err)
}
if !historical {

// TODO: this won't work for Arbitrum
// TODO: we disallow syncing historical events here
Expand All @@ -143,29 +145,22 @@ func RecordSignature(
consensus.Add(key, make(map[bls12381.G1Affine]big.Int))
}

// TODO: This will lead to too many PoS requests
userStake, err := pos.GetVotingPowerOfPublicKey(signer.PublicKey)

var votingPower *big.Int
var totalVoted *big.Int

base := big.NewInt(0)
base.SetString(config.Config.GetString("pos.base"), 10)

nft := big.NewInt(0)
nft.SetString(config.Config.GetString("pos.nft"), 10)
votingPower, err := pos.GetVotingPowerOfPublicKey(
signer.PublicKey,
big.NewInt(int64(*blockNumber)),
)

if err != nil {
votingPower = base
} else {
tokenPower := new(big.Int).Add(userStake.Amount, base)
nftPower := new(big.Int).Mul(nft, big.NewInt(int64(len(userStake.NftIds))))
votingPower = new(big.Int).Add(tokenPower, nftPower)
log.Logger.
With("Address", address.Calculate(signer.PublicKey[:])).
With("Error", err).
Error("Failed to get voting power")
return
}

reportedValues, _ := consensus.Get(key)
voted := reportedValues[hash]
totalVoted = new(big.Int).Add(votingPower, &voted)
totalVoted := new(big.Int).Add(votingPower, &voted)
isMajority := true

for _, reportCount := range reportedValues {
Expand Down
50 changes: 22 additions & 28 deletions src/plugins/uniswap/uniswap.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,19 +88,20 @@ func RecordSignature(
return
}

if !historical {
blockNumber, err := GetBlockNumber(info.Asset.Token.Chain)
// TODO: Standalone mode shouldn't call this or check consensus
blockNumber, err := GetBlockNumber(info.Asset.Token.Chain)

if err != nil {
log.Logger.
With("Network", info.Asset.Token.Chain).
With("Error", err).
Error("Failed to get the latest block number")
ethereum.RefreshRPC(info.Asset.Token.Chain)
// TODO: we should retry
return
}
if err != nil {
log.Logger.
With("Network", info.Asset.Token.Chain).
With("Error", err).
Error("Failed to get the latest block number")
ethereum.RefreshRPC(info.Asset.Token.Chain)
// TODO: we should retry
return
}

if !historical {
// TODO: this won't work for Arbitrum
if *blockNumber-info.Asset.Block > 96 {
log.Logger.
Expand All @@ -126,27 +127,20 @@ func RecordSignature(
voted = *big.NewInt(0)
}

// TODO: This will lead to too many PoS requests
userStake, err := pos.GetVotingPowerOfPublicKey(signer.PublicKey)

var votingPower *big.Int
var totalVoted *big.Int

base := big.NewInt(0)
base.SetString(config.Config.GetString("pos.base"), 10)

nft := big.NewInt(0)
nft.SetString(config.Config.GetString("pos.nft"), 10)
votingPower, err := pos.GetVotingPowerOfPublicKey(
signer.PublicKey,
big.NewInt(int64(*blockNumber)),
)

if err != nil {
votingPower = base
} else {
tokenPower := new(big.Int).Add(userStake.Amount, base)
nftPower := new(big.Int).Mul(nft, big.NewInt(int64(len(userStake.NftIds))))
votingPower = new(big.Int).Add(tokenPower, nftPower)
log.Logger.
With("Address", address.Calculate(signer.PublicKey[:])).
With("Error", err).
Error("Failed to get voting power")
return
}

totalVoted = new(big.Int).Add(votingPower, &voted)
totalVoted := new(big.Int).Add(votingPower, &voted)

reportedValues.Range(func(_ bls12381.G1Affine, value big.Int) bool {
if value.Cmp(totalVoted) == 1 {
Expand Down
98 changes: 72 additions & 26 deletions src/pos/pos.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,77 @@ import (
)

var posContract *contracts.UnchainedStaking
var votingPowers map[[20]byte]big.Int
var stakes map[[20]byte]contracts.UnchainedStakingStake

func GetTotalVotingPower() (*big.Int, error) {
return posContract.TotalVotingPower(nil)
}

func GetVotingPower(address [20]byte) (contracts.UnchainedStakingStake, error) {
func GetStake(address [20]byte, block *big.Int) (contracts.UnchainedStakingStake, error) {
cached, ok := stakes[address]

if ok && cached.Unlock.Cmp(block) >= 0 {
return cached, nil
}

stake, err := posContract.StakeOf0(nil, address)

if err == nil {
if stake.Amount.Cmp(big.NewInt(0)) == 0 {
// TODO: we should listen to stake changed events
// TODO: and update stakes accordingly
stake.Unlock = new(big.Int).Add(block, big.NewInt(25000))
}

stakes[address] = stake
}

return stake, err
}

func GetVotingPowerOfPublicKey(pkBytes [96]byte) (contracts.UnchainedStakingStake, error) {
func GetVotingPower(address [20]byte, block *big.Int) (*big.Int, error) {

if votingPower, ok := votingPowers[address]; ok {
return &votingPower, nil
}

stake, err := GetStake(address, block)

if err != nil {
return nil, err
}

base := big.NewInt(0)
base.SetString(config.Config.GetString("pos.base"), 10)

nft := big.NewInt(0)
nft.SetString(config.Config.GetString("pos.nft"), 10)

nftPower := new(big.Int).Mul(nft, big.NewInt(int64(len(stake.NftIds))))
votingPower := new(big.Int).Add(stake.Amount, nftPower)

if votingPower.Cmp(base) < 0 {
votingPower = base
}

votingPowers[address] = *votingPower
return votingPower, nil
}

func GetVotingPowerOfPublicKey(
pkBytes [96]byte,
block *big.Int,
) (*big.Int, error) {
_, addrHex := address.CalculateHex(pkBytes[:])
stake, err := posContract.StakeOf0(nil, addrHex)
return stake, err
return GetVotingPower(addrHex, block)
}

func VotingPowerToFloat(power *big.Int) *big.Float {
decimalPlaces := big.NewInt(1e18)
powerFloat := new(big.Float).SetInt(power)
powerFloat.Quo(powerFloat, new(big.Float).SetInt(decimalPlaces))
return powerFloat
}

func Start() {
Expand All @@ -35,8 +92,8 @@ func Start() {
addrHexStr, addrHex := address.CalculateHex(pkBytes[:])

log.Logger.
With("Link", addrHexStr).
Info("Unchained EVM")
With("Hex", addrHexStr).
Info("Unchained")

var err error

Expand All @@ -54,27 +111,16 @@ func Start() {
os.Exit(1)
}

stake, _ := GetVotingPower(addrHex)
power, _ := GetVotingPower(addrHex, big.NewInt(0))
total, _ := GetTotalVotingPower()

var votingPower *big.Int

base := big.NewInt(0)
base.SetString(config.Config.GetString("pos.base"), 10)

nft := big.NewInt(0)
nft.SetString(config.Config.GetString("pos.nft"), 10)

if err != nil {
votingPower = base
} else {
tokenPower := new(big.Int).Add(stake.Amount, base)
nftPower := new(big.Int).Mul(nft, big.NewInt(int64(len(stake.NftIds))))
votingPower = new(big.Int).Add(tokenPower, nftPower)
}

log.Logger.
With("Power", votingPower.String()).
With("Network", total.String()).
Info("Voting power")
With("Power", VotingPowerToFloat(power)).
With("Network", VotingPowerToFloat(total)).
Info("PoS")
}

func init() {
votingPowers = make(map[[20]byte]big.Int)
stakes = make(map[[20]byte]contracts.UnchainedStakingStake)
}
8 changes: 5 additions & 3 deletions src/utils/debounce.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,12 @@ func Debounce[KeyType comparable, ArgType any](

context.timers[key] = time.AfterFunc(wait, func() {
context.Lock()
defer context.Unlock()

delete(context.timers, key)
function(arg)

go func() {
defer context.Unlock()
function(arg)
}()
})
}
}

0 comments on commit b971402

Please sign in to comment.