Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parallel decryptions: use tx hash instead of block hash in auto-seeding #152

Merged
merged 6 commits into from
Sep 23, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion go-ethereum
3 changes: 3 additions & 0 deletions hooks/hooks.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package hooks

import (
"encoding/hex"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/log"
Expand Down Expand Up @@ -153,6 +154,8 @@ func (h FheOSHooksImpl) EvmCallEnd(evmSuccess bool) {
log.Info("Deleted ciphertext", "hash", hex.EncodeToString(hash[:]))
}
}

fheos.State.RandomCounter = 0
}

func shouldIgnoreContract(caller common.Address, addr common.Address) bool {
Expand Down
39 changes: 38 additions & 1 deletion nitro-overrides/execution/gethexec/tx_ops_graph.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package gethexec

import (
"errors"
"sync"
"time"

"github.com/ethereum/go-ethereum/arbitrum_types"
Expand All @@ -25,6 +27,8 @@ type decryption struct {
}

type TxOpsGraph struct {
mu sync.Mutex

transactions map[common.Hash]*transaction
decryptions map[fheos.PendingDecryption]*decryption
}
Expand All @@ -37,6 +41,9 @@ func NewTxOpsGraph() *TxOpsGraph {
}

func (bg *TxOpsGraph) AddEdge(gethtx *geth.Transaction, txOptions *arbitrum_types.ConditionalOptions, decryptKey fheos.PendingDecryption) {
bg.mu.Lock()
defer bg.mu.Unlock()

tx := bg.addTransaction(gethtx, txOptions)
decrypt := bg.addDecryption(decryptKey)

Expand All @@ -45,10 +52,16 @@ func (bg *TxOpsGraph) AddEdge(gethtx *geth.Transaction, txOptions *arbitrum_type
}

func (bg *TxOpsGraph) ResolveTransaction(txHash common.Hash) {
bg.mu.Lock()
defer bg.mu.Unlock()

bg.removeTransaction(txHash)
}

func (bg *TxOpsGraph) ResolveDecryption(decryptKey fheos.PendingDecryption) []*transaction {
bg.mu.Lock()
defer bg.mu.Unlock()

decrypt, exists := bg.decryptions[decryptKey]
if !exists {
return nil
Expand All @@ -61,14 +74,21 @@ func (bg *TxOpsGraph) ResolveDecryption(decryptKey fheos.PendingDecryption) []*t
tx.resolvedDecryptions[decryptKey] = decrypt

if len(tx.pendingDecryptions) == 0 {
pushedTransactions = append(pushedTransactions, tx)
if tx.Retries > 5 /* TODO this number is just a placeholder */ {
bg.rejectTransaction(tx.Tx.Hash(), errors.New("transaction rejected after 5 retries"))
} else {
pushedTransactions = append(pushedTransactions, tx)
}
}
}

return pushedTransactions
}

func (bg *TxOpsGraph) SetTxQueueItem(queueItem txQueueItem) {
bg.mu.Lock()
defer bg.mu.Unlock()

txHash := queueItem.tx.Hash()
tx, exists := bg.transactions[txHash]
if !exists {
Expand Down Expand Up @@ -126,3 +146,20 @@ func (bg *TxOpsGraph) removeTransaction(txHash common.Hash) {

delete(bg.transactions, txHash)
}

func (bg *TxOpsGraph) rejectTransaction(txHash common.Hash, customErr error) error {
tx, exists := bg.transactions[txHash]
if !exists {
return nil // Transaction not found, nothing to reject
}

// Remove the transaction from the graph
bg.removeTransaction(txHash)

// Check if the queueItem is still valid
if tx.QueueItem != nil && tx.QueueItem.ctx.Err() == nil {
tx.QueueItem.returnResult(customErr)
}

return nil
}
22 changes: 4 additions & 18 deletions precompiles/contracts.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"os"
"strings"

"github.com/ethereum/go-ethereum/common"
"github.com/fhenixprotocol/fheos/precompiles/types"
storage2 "github.com/fhenixprotocol/fheos/storage"
"github.com/fhenixprotocol/warp-drive/fhe-driver"
Expand Down Expand Up @@ -1556,29 +1555,16 @@ func Random(utype byte, seed uint64, securityZone int32, tp *TxParams) ([]byte,
if seed != 0 {
finalSeed = seed
} else {
// Seed generation
// The current block hash is not yet calculated, se we use the previous block hash
var prevBlockHash = common.Hash{}

if tp.BlockNumber != nil {
prevBlockNumber := tp.BlockNumber.Uint64() - 1
prevBlockHash = tp.GetBlockHash(prevBlockNumber)
} else {
logger.Warn("missing BlockNumber inside precompile")
}

var randomCounter uint64
if tp.Commit {
// We're incrementing nonce regardless of whether the transaction is successful or not,
// so that even after a revert, the random is different.
// Secondly, we're incrementing before the request for the random number, so that queries
// We're incrementing before the request for the random number, so that queries
// that came before this Tx would have received a different seed.
randomCounter = State.IncRandomCounter(prevBlockHash)
randomCounter = State.IncRandomCounter()
} else {
randomCounter = State.GetRandomCounter(prevBlockHash)
randomCounter = State.GetRandomCounter()
}

finalSeed = GenerateSeedFromEntropy(tp.ContractAddress, prevBlockHash, randomCounter)
finalSeed = GenerateSeedFromEntropy(tp.ContractAddress, tp.TxContext.Hash, randomCounter)
}

result, err := fhe.FheRandom(securityZone, uintType, finalSeed)
Expand Down
25 changes: 4 additions & 21 deletions precompiles/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"time"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/metrics"
"github.com/fhenixprotocol/fheos/precompiles/types"
storage2 "github.com/fhenixprotocol/fheos/storage"
Expand Down Expand Up @@ -74,28 +73,12 @@ func (fs *FheosState) SetCiphertext(ct *types.CipherTextRepresentation) error {
return result
}

func (fs *FheosState) GetRandomCounter(latestHash common.Hash) uint64 {
if fs.LastSavedHash == nil || *fs.LastSavedHash != latestHash {
return 0
} else if *fs.LastSavedHash == latestHash {
return fs.RandomCounter
}

logger.Warn("unexpected error in GetRandomCounter")
return 0
func (fs *FheosState) GetRandomCounter() uint64 {
return fs.RandomCounter
}

func (fs *FheosState) IncRandomCounter(latestHash common.Hash) uint64 {
if fs.LastSavedHash == nil || *fs.LastSavedHash != latestHash {
fs.LastSavedHash = &latestHash
fs.RandomCounter = 1
log.Debug("new block, counter reset on increment", "counter", fs.RandomCounter)
} else if *fs.LastSavedHash == latestHash {
fs.RandomCounter += 1
log.Debug("counter incremented", "counter", fs.RandomCounter)
} else {
logger.Warn("unexpected error in IncRandomCounter")
}
func (fs *FheosState) IncRandomCounter() uint64 {
fs.RandomCounter += 1

return fs.RandomCounter
}
Expand Down
9 changes: 6 additions & 3 deletions precompiles/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ type TxParams struct {
GetBlockHash vm.GetHashFunc
BlockNumber *big.Int
ParallelTxHooks types.ParallelTxProcessingHook
vm.TxContext
}

type GasBurner interface {
Expand All @@ -50,6 +51,8 @@ func TxParamsFromEVM(evm *vm.EVM, callerContract common.Address) TxParams {
tp.ParallelTxHooks = nil
}

tp.TxContext = evm.TxContext

return tp
}

Expand Down Expand Up @@ -126,11 +129,11 @@ func evaluateRequire(ct *fhe.FheEncrypted) bool {
return fhe.Require(ct)
}

func GenerateSeedFromEntropy(contractAddress common.Address, prevBlockHash common.Hash, randomCounter uint64) uint64 {
data := make([]byte, 0, len(contractAddress)+len(prevBlockHash)+8) // 8 bytes for uint64
func GenerateSeedFromEntropy(contractAddress common.Address, txHash common.Hash, randomCounter uint64) uint64 {
data := make([]byte, 0, len(contractAddress)+len(txHash)+8) // 8 bytes for uint64

data = append(data, contractAddress[:]...)
data = append(data, prevBlockHash[:]...)
data = append(data, txHash[:]...)

uint64Bytes := make([]byte, 8)
binary.BigEndian.PutUint64(uint64Bytes, randomCounter)
Expand Down
Loading