diff --git a/src/avalanche/proofbuilder.cpp b/src/avalanche/proofbuilder.cpp
index 1144496bc..d7e9ac370 100644
--- a/src/avalanche/proofbuilder.cpp
+++ b/src/avalanche/proofbuilder.cpp
@@ -1,83 +1,72 @@
 // Copyright (c) 2020 The Bitcoin developers
 // Distributed under the MIT software license, see the accompanying
 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
 
 #include <avalanche/proofbuilder.h>
 
 #include <random.h>
 #include <util/system.h>
 
 namespace avalanche {
 
-SignedStake ProofBuilder::StakeSigner::sign(const StakeCommitment &commitment) {
-    const uint256 h = stake.getHash(commitment);
-
-    SchnorrSig sig;
-    if (!key.SignSchnorr(h, sig)) {
-        sig.fill(0);
-    }
-
-    return SignedStake(std::move(stake), std::move(sig));
-}
-
 bool ProofBuilder::addUTXO(COutPoint utxo, Amount amount, uint32_t height,
                            bool is_coinbase, CKey key) {
     if (!key.IsValid()) {
         return false;
     }
 
-    return stakes
-        .emplace(Stake(std::move(utxo), amount, height, is_coinbase,
-                       key.GetPubKey()),
-                 std::move(key))
-        .second;
+    const StakeCommitment commitment(getProofId(), expirationTime,
+                                     masterKey.GetPubKey());
+    auto stake =
+        Stake(std::move(utxo), amount, height, is_coinbase, key.GetPubKey());
+    const uint256 h = stake.getHash(commitment);
+    SchnorrSig sig;
+    if (!key.SignSchnorr(h, sig)) {
+        sig.fill(0);
+    }
+
+    return stakes.emplace(std::move(stake), std::move(sig)).second;
 }
 
 ProofRef ProofBuilder::build() {
     SchnorrSig proofSignature;
     const LimitedProofId limitedProofId = getLimitedProofId();
     if (!masterKey.SignSchnorr(limitedProofId, proofSignature)) {
         proofSignature.fill(0);
     }
-
-    const ProofId proofid = getProofId();
-
-    const StakeCommitment commitment(proofid, expirationTime,
-                                     masterKey.GetPubKey());
-
     std::vector<SignedStake> signedStakes;
     signedStakes.reserve(stakes.size());
 
     while (!stakes.empty()) {
         auto handle = stakes.extract(stakes.begin());
-        signedStakes.push_back(handle.value().sign(commitment));
+        signedStakes.push_back(handle.value());
     }
 
     return ProofRef::make(sequence, expirationTime, masterKey.GetPubKey(),
                           std::move(signedStakes), payoutScriptPubKey,
                           std::move(proofSignature));
 }
 
 LimitedProofId ProofBuilder::getLimitedProofId() const {
     CHashWriter ss(SER_GETHASH, 0);
     ss << sequence;
     ss << expirationTime;
     ss << payoutScriptPubKey;
 
     WriteCompactSize(ss, stakes.size());
     for (const auto &s : stakes) {
-        ss << s.stake;
+        ss << s.getStake();
     }
 
     return LimitedProofId(ss.GetHash());
 }
 
 ProofId ProofBuilder::getProofId() const {
     CHashWriter ss(SER_GETHASH, 0);
     ss << getLimitedProofId();
     ss << masterKey.GetPubKey();
 
     return ProofId(ss.GetHash());
 }
 
 } // namespace avalanche
diff --git a/src/avalanche/proofbuilder.h b/src/avalanche/proofbuilder.h
index a023dd862..b9afc7157 100644
--- a/src/avalanche/proofbuilder.h
+++ b/src/avalanche/proofbuilder.h
@@ -1,61 +1,51 @@
 // Copyright (c) 2020 The Bitcoin developers
 // Distributed under the MIT software license, see the accompanying
 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
 
 #ifndef BITCOIN_AVALANCHE_PROOFBUILDER_H
 #define BITCOIN_AVALANCHE_PROOFBUILDER_H
 
 #include <avalanche/proof.h>
 #include <key.h>
 
 #include <cstdio>
 
 namespace avalanche {
 
 struct TestProofBuilder;
 
 class ProofBuilder {
     uint64_t sequence;
     int64_t expirationTime;
     CKey masterKey;
     CScript payoutScriptPubKey;
 
-    struct StakeSigner {
-        Stake stake;
-        CKey key;
-
-        StakeSigner(Stake stake_, CKey key_)
-            : stake(std::move(stake_)), key(std::move(key_)) {}
-
-        SignedStake sign(const StakeCommitment &commitment);
-    };
-
-    struct StakeSignerComparator {
-        bool operator()(const StakeSigner &lhs, const StakeSigner &rhs) const {
-            return lhs.stake.getId() < rhs.stake.getId();
+    struct SignedStakeComparator {
+        bool operator()(const SignedStake &lhs, const SignedStake &rhs) const {
+            return lhs.getStake().getId() < rhs.getStake().getId();
         }
     };
-    std::set<StakeSigner, StakeSignerComparator> stakes;
+    std::set<SignedStake, SignedStakeComparator> stakes;
 
 public:
     ProofBuilder(uint64_t sequence_, int64_t expirationTime_, CKey masterKey_,
                  const CScript &payoutScriptPubKey_)
         : sequence(sequence_), expirationTime(expirationTime_),
           masterKey(std::move(masterKey_)),
           payoutScriptPubKey(payoutScriptPubKey_) {}
 
     [[nodiscard]] bool addUTXO(COutPoint utxo, Amount amount, uint32_t height,
                                bool is_coinbase, CKey key);
 
     ProofRef build();
 
 private:
     LimitedProofId getLimitedProofId() const;
     ProofId getProofId() const;
 
     friend struct TestProofBuilder;
 };
 
 } // namespace avalanche
 
 #endif // BITCOIN_AVALANCHE_PROOFBUILDER_H
diff --git a/src/avalanche/test/util.cpp b/src/avalanche/test/util.cpp
index a5e119b53..a5bef5cf4 100644
--- a/src/avalanche/test/util.cpp
+++ b/src/avalanche/test/util.cpp
@@ -1,134 +1,134 @@
 // Copyright (c) 2020 The Bitcoin developers
 // Distributed under the MIT software license, see the accompanying
 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
 
 #include <amount.h>
 #include <avalanche/proofbuilder.h>
 #include <avalanche/test/util.h>
 #include <key.h>
 #include <primitives/transaction.h>
 #include <random.h>
 #include <script/standard.h>
 #include <validation.h>
 
 #include <boost/test/unit_test.hpp>
 
 #include <limits>
 
 namespace avalanche {
 
 ProofRef buildRandomProof(CChainState &active_chainstate, uint32_t score,
                           int height, const CKey &masterKey) {
     auto key = CKey::MakeCompressedKey();
 
     const COutPoint o(TxId(GetRandHash()), 0);
     const Amount v = (int64_t(score) * COIN) / 100;
     const bool is_coinbase = false;
 
     {
         CScript script = GetScriptForDestination(PKHash(key.GetPubKey()));
 
         LOCK(cs_main);
         CCoinsViewCache &coins = active_chainstate.CoinsTip();
         coins.AddCoin(o, Coin(CTxOut(v, script), height, is_coinbase), false);
     }
 
     ProofBuilder pb(0, std::numeric_limits<uint32_t>::max(), masterKey,
                     UNSPENDABLE_ECREG_PAYOUT_SCRIPT);
     BOOST_CHECK(pb.addUTXO(o, v, height, is_coinbase, std::move(key)));
     return pb.build();
 }
 
 bool hasDustStake(const ProofRef &proof) {
     for (const SignedStake &s : proof->getStakes()) {
         if (s.getStake().getAmount() < PROOF_DUST_THRESHOLD) {
             return true;
         }
     }
     return false;
 }
 
 LimitedProofId
 TestProofBuilder::getReverseOrderLimitedProofId(ProofBuilder &pb) {
     CHashWriter ss(SER_GETHASH, 0);
     ss << pb.sequence;
     ss << pb.expirationTime;
     ss << pb.payoutScriptPubKey;
 
     WriteCompactSize(ss, pb.stakes.size());
     for (auto it = pb.stakes.rbegin(); it != pb.stakes.rend(); it++) {
-        ss << it->stake;
+        ss << it->getStake();
     }
 
     return LimitedProofId(ss.GetHash());
 }
 
 ProofRef TestProofBuilder::buildWithReversedOrderStakes(ProofBuilder &pb) {
     const LimitedProofId limitedProofid =
         TestProofBuilder::getReverseOrderLimitedProofId(pb);
     const CPubKey masterPubKey = pb.masterKey.GetPubKey();
     const StakeCommitment commitment(
         limitedProofid.computeProofId(masterPubKey), pb.expirationTime,
         pb.masterKey.GetPubKey());
 
     std::vector<SignedStake> signedStakes;
     signedStakes.reserve(pb.stakes.size());
 
     while (!pb.stakes.empty()) {
         // We need a forward iterator, so pb.stakes.rbegin() is not an
         // option.
         auto handle = pb.stakes.extract(std::prev(pb.stakes.end()));
-        signedStakes.push_back(handle.value().sign(commitment));
+        signedStakes.push_back(handle.value());
     }
 
     SchnorrSig proofSignature;
     BOOST_CHECK(pb.masterKey.SignSchnorr(limitedProofid, proofSignature));
 
     return ProofRef::make(pb.sequence, pb.expirationTime, masterPubKey,
                           std::move(signedStakes), pb.payoutScriptPubKey,
                           proofSignature);
 }
 
 LimitedProofId
 TestProofBuilder::getDuplicatedStakeLimitedProofId(ProofBuilder &pb) {
     CHashWriter ss(SER_GETHASH, 0);
     ss << pb.sequence;
     ss << pb.expirationTime;
     ss << pb.payoutScriptPubKey;
 
     WriteCompactSize(ss, 2 * pb.stakes.size());
     for (auto &s : pb.stakes) {
-        ss << s.stake;
-        ss << s.stake;
+        ss << s.getStake();
+        ss << s.getStake();
     }
 
     return LimitedProofId(ss.GetHash());
 }
 
 ProofRef TestProofBuilder::buildDuplicatedStakes(ProofBuilder &pb) {
     const LimitedProofId limitedProofid =
         TestProofBuilder::getDuplicatedStakeLimitedProofId(pb);
     const CPubKey masterPubKey = pb.masterKey.GetPubKey();
     const StakeCommitment commitment(
         limitedProofid.computeProofId(masterPubKey), pb.expirationTime,
         pb.masterKey.GetPubKey());
 
     std::vector<SignedStake> signedStakes;
     signedStakes.reserve(2 * pb.stakes.size());
 
     while (!pb.stakes.empty()) {
         auto handle = pb.stakes.extract(pb.stakes.begin());
-        SignedStake signedStake = handle.value().sign(commitment);
+        SignedStake signedStake = handle.value();
         signedStakes.push_back(signedStake);
         signedStakes.push_back(signedStake);
     }
 
     SchnorrSig proofSignature;
     BOOST_CHECK(pb.masterKey.SignSchnorr(limitedProofid, proofSignature));
 
     return ProofRef::make(pb.sequence, pb.expirationTime, masterPubKey,
                           std::move(signedStakes), pb.payoutScriptPubKey,
                           proofSignature);
 }
 
 } // namespace avalanche