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

Add OnPersist for NativeContracts #751

Merged
merged 2 commits into from
May 16, 2019
Merged
Show file tree
Hide file tree
Changes from all 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: 0 additions & 2 deletions neo.UnitTests/TestBlockchain.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ public static NeoSystem InitializeMockNeoSystem()
mockSnapshot.SetupGet(p => p.Contracts).Returns(new TestDataCache<UInt160, ContractState>());
mockSnapshot.SetupGet(p => p.Storages).Returns(new TestDataCache<StorageKey, StorageItem>());
mockSnapshot.SetupGet(p => p.HeaderHashList).Returns(new TestDataCache<UInt32Wrapper, HeaderHashList>());
mockSnapshot.SetupGet(p => p.NextValidators).Returns(new TestMetaDataCache<NextValidatorsState>());
mockSnapshot.SetupGet(p => p.BlockHashIndex).Returns(new TestMetaDataCache<HashIndexState>());
mockSnapshot.SetupGet(p => p.HeaderHashIndex).Returns(new TestMetaDataCache<HashIndexState>());

Expand All @@ -45,7 +44,6 @@ public static NeoSystem InitializeMockNeoSystem()
_Store.Setup(p => p.GetContracts()).Returns(new TestDataCache<UInt160, ContractState>());
_Store.Setup(p => p.GetStorages()).Returns(new TestDataCache<StorageKey, StorageItem>());
_Store.Setup(p => p.GetHeaderHashList()).Returns(new TestDataCache<UInt32Wrapper, HeaderHashList>());
_Store.Setup(p => p.GetNextValidators()).Returns(new TestMetaDataCache<NextValidatorsState>());
_Store.Setup(p => p.GetBlockHashIndex()).Returns(new TestMetaDataCache<HashIndexState>());
_Store.Setup(p => p.GetHeaderHashIndex()).Returns(new TestMetaDataCache<HashIndexState>());
_Store.Setup(p => p.GetSnapshot()).Returns(mockSnapshot.Object);
Expand Down
5 changes: 3 additions & 2 deletions neo/Consensus/ConsensusContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using Neo.Persistence;
using Neo.Plugins;
using Neo.SmartContract;
using Neo.SmartContract.Native;
using Neo.Wallets;
using System;
using System.Collections.Generic;
Expand Down Expand Up @@ -276,10 +277,10 @@ public void Reset(byte viewNumber)
{
PrevHash = Snapshot.CurrentBlockHash,
Index = Snapshot.Height + 1,
NextConsensus = Blockchain.GetConsensusAddress(Snapshot.GetValidators().ToArray()),
NextConsensus = Blockchain.GetConsensusAddress(NativeContract.NEO.GetValidators(Snapshot).ToArray()),
ConsensusData = new ConsensusData()
};
Validators = Snapshot.NextValidators.Get().Validators;
Validators = NativeContract.NEO.GetNextBlockValidators(Snapshot);
MyIndex = -1;
ChangeViewPayloads = new ConsensusPayload[Validators.Length];
LastChangeViewPayloads = new ConsensusPayload[Validators.Length];
Expand Down
5 changes: 3 additions & 2 deletions neo/Ledger/Blockchain.cs
Original file line number Diff line number Diff line change
Expand Up @@ -414,11 +414,13 @@ private void Persist(Block block)
snapshot.PersistingBlock = block;
if (block.Index > 0)
{
NativeContract[] contracts = { NativeContract.GAS, NativeContract.NEO };
using (ApplicationEngine engine = new ApplicationEngine(TriggerType.System, null, snapshot, 0, true))
{
using (ScriptBuilder sb = new ScriptBuilder())
{
sb.EmitAppCall(NativeContract.GAS.ScriptHash, "distributeFees");
foreach (NativeContract contract in contracts)
sb.EmitAppCall(contract.ScriptHash, "onPersist");
engine.LoadScript(sb.ToArray());
}
engine.Execute();
Expand All @@ -427,7 +429,6 @@ private void Persist(Block block)
Context.System.EventStream.Publish(application_executed);
all_application_executed.Add(application_executed);
}
snapshot.NextValidators.GetAndChange().Validators = snapshot.GetValidators();
}
snapshot.Blocks.Add(block.Hash, new BlockState
{
Expand Down
38 changes: 0 additions & 38 deletions neo/Ledger/NextValidatorsState.cs

This file was deleted.

3 changes: 2 additions & 1 deletion neo/Network/P2P/Payloads/ConsensusPayload.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using Neo.IO;
using Neo.Persistence;
using Neo.SmartContract;
using Neo.SmartContract.Native;
using System;
using System.IO;

Expand Down Expand Up @@ -92,7 +93,7 @@ void IVerifiable.DeserializeUnsigned(BinaryReader reader)

UInt160[] IVerifiable.GetScriptHashesForVerifying(Snapshot snapshot)
{
ECPoint[] validators = snapshot.NextValidators.Get().Validators;
ECPoint[] validators = NativeContract.NEO.GetNextBlockValidators(snapshot);
if (validators.Length <= ValidatorIndex)
throw new InvalidOperationException();
return new[] { Contract.CreateSignatureRedeemScript(validators[ValidatorIndex]).ToScriptHash() };
Expand Down
4 changes: 2 additions & 2 deletions neo/Network/RPC/RpcServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -551,8 +551,8 @@ private JObject GetValidators()
{
using (Snapshot snapshot = Blockchain.Singleton.GetSnapshot())
{
var validators = snapshot.GetValidators();
return snapshot.GetRegisteredValidators().Select(p =>
var validators = NativeContract.NEO.GetValidators(snapshot);
return NativeContract.NEO.GetRegisteredValidators(snapshot).Select(p =>
{
JObject validator = new JObject();
validator["publickey"] = p.PublicKey.ToString();
Expand Down
2 changes: 0 additions & 2 deletions neo/Persistence/CloneSnapshot.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ internal class CloneSnapshot : Snapshot
public override DataCache<UInt160, ContractState> Contracts { get; }
public override DataCache<StorageKey, StorageItem> Storages { get; }
public override DataCache<UInt32Wrapper, HeaderHashList> HeaderHashList { get; }
public override MetaDataCache<NextValidatorsState> NextValidators { get; }
public override MetaDataCache<HashIndexState> BlockHashIndex { get; }
public override MetaDataCache<HashIndexState> HeaderHashIndex { get; }

Expand All @@ -23,7 +22,6 @@ public CloneSnapshot(Snapshot snapshot)
this.Contracts = snapshot.Contracts.CreateSnapshot();
this.Storages = snapshot.Storages.CreateSnapshot();
this.HeaderHashList = snapshot.HeaderHashList.CreateSnapshot();
this.NextValidators = snapshot.NextValidators.CreateSnapshot();
this.BlockHashIndex = snapshot.BlockHashIndex.CreateSnapshot();
this.HeaderHashIndex = snapshot.HeaderHashIndex.CreateSnapshot();
}
Expand Down
1 change: 0 additions & 1 deletion neo/Persistence/IPersistence.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ public interface IPersistence
DataCache<UInt160, ContractState> Contracts { get; }
DataCache<StorageKey, StorageItem> Storages { get; }
DataCache<UInt32Wrapper, HeaderHashList> HeaderHashList { get; }
MetaDataCache<NextValidatorsState> NextValidators { get; }
MetaDataCache<HashIndexState> BlockHashIndex { get; }
MetaDataCache<HashIndexState> HeaderHashIndex { get; }
}
Expand Down
2 changes: 0 additions & 2 deletions neo/Persistence/LevelDB/DbSnapshot.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ internal class DbSnapshot : Snapshot
public override DataCache<UInt160, ContractState> Contracts { get; }
public override DataCache<StorageKey, StorageItem> Storages { get; }
public override DataCache<UInt32Wrapper, HeaderHashList> HeaderHashList { get; }
public override MetaDataCache<NextValidatorsState> NextValidators { get; }
public override MetaDataCache<HashIndexState> BlockHashIndex { get; }
public override MetaDataCache<HashIndexState> HeaderHashIndex { get; }

Expand All @@ -32,7 +31,6 @@ public DbSnapshot(DB db)
Contracts = new DbCache<UInt160, ContractState>(db, options, batch, Prefixes.ST_Contract);
Storages = new DbCache<StorageKey, StorageItem>(db, options, batch, Prefixes.ST_Storage);
HeaderHashList = new DbCache<UInt32Wrapper, HeaderHashList>(db, options, batch, Prefixes.IX_HeaderHashList);
NextValidators = new DbMetaDataCache<NextValidatorsState>(db, options, batch, Prefixes.IX_NextValidators);
BlockHashIndex = new DbMetaDataCache<HashIndexState>(db, options, batch, Prefixes.IX_CurrentBlock);
HeaderHashIndex = new DbMetaDataCache<HashIndexState>(db, options, batch, Prefixes.IX_CurrentHeader);
}
Expand Down
5 changes: 0 additions & 5 deletions neo/Persistence/LevelDB/LevelDBStore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,6 @@ public override DataCache<UInt32Wrapper, HeaderHashList> GetHeaderHashList()
return new DbCache<UInt32Wrapper, HeaderHashList>(db, null, null, Prefixes.IX_HeaderHashList);
}

public override MetaDataCache<NextValidatorsState> GetNextValidators()
{
return new DbMetaDataCache<NextValidatorsState>(db, null, null, Prefixes.IX_NextValidators);
}

public override MetaDataCache<HashIndexState> GetBlockHashIndex()
{
return new DbMetaDataCache<HashIndexState>(db, null, null, Prefixes.IX_CurrentBlock);
Expand Down
1 change: 0 additions & 1 deletion neo/Persistence/LevelDB/Prefixes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ internal static class Prefixes
public const byte ST_Storage = 0x70;

public const byte IX_HeaderHashList = 0x80;
public const byte IX_NextValidators = 0x90;
public const byte IX_CurrentBlock = 0xc0;
public const byte IX_CurrentHeader = 0xc1;

Expand Down
46 changes: 1 addition & 45 deletions neo/Persistence/Snapshot.cs
Original file line number Diff line number Diff line change
@@ -1,18 +1,8 @@
using Neo.Cryptography.ECC;
using Neo.IO;
using Neo.IO.Caching;
using Neo.IO.Caching;
using Neo.IO.Wrappers;
using Neo.Ledger;
using Neo.Network.P2P.Payloads;
using Neo.SmartContract;
using Neo.SmartContract.Native;
using Neo.VM;
using Neo.VM.Types;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using VMArray = Neo.VM.Types.Array;

namespace Neo.Persistence
{
Expand All @@ -24,7 +14,6 @@ public abstract class Snapshot : IDisposable, IPersistence
public abstract DataCache<UInt160, ContractState> Contracts { get; }
public abstract DataCache<StorageKey, StorageItem> Storages { get; }
public abstract DataCache<UInt32Wrapper, HeaderHashList> HeaderHashList { get; }
public abstract MetaDataCache<NextValidatorsState> NextValidators { get; }
public abstract MetaDataCache<HashIndexState> BlockHashIndex { get; }
public abstract MetaDataCache<HashIndexState> HeaderHashIndex { get; }

Expand All @@ -45,45 +34,12 @@ public virtual void Commit()
Contracts.Commit();
Storages.Commit();
HeaderHashList.Commit();
NextValidators.Commit();
BlockHashIndex.Commit();
HeaderHashIndex.Commit();
}

public virtual void Dispose()
{
}

public IEnumerable<(ECPoint PublicKey, BigInteger Votes)> GetRegisteredValidators()
{
byte[] script;
using (ScriptBuilder sb = new ScriptBuilder())
{
sb.EmitAppCall(NativeContract.NEO.ScriptHash, "getRegisteredValidators");
script = sb.ToArray();
}
using (ApplicationEngine engine = ApplicationEngine.Run(script, this, testMode: true))
{
return ((VMArray)engine.ResultStack.Peek()).Select(p =>
{
Struct @struct = (Struct)p;
return (@struct.GetByteArray().AsSerializable<ECPoint>(), @struct.GetBigInteger());
});
}
}

public ECPoint[] GetValidators()
{
byte[] script;
using (ScriptBuilder sb = new ScriptBuilder())
{
sb.EmitAppCall(NativeContract.NEO.ScriptHash, "getValidators");
script = sb.ToArray();
}
using (ApplicationEngine engine = ApplicationEngine.Run(script, this, testMode: true))
{
return ((VMArray)engine.ResultStack.Peek()).Select(p => p.GetByteArray().AsSerializable<ECPoint>()).ToArray();
}
}
}
}
2 changes: 0 additions & 2 deletions neo/Persistence/Store.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ public abstract class Store : IPersistence
DataCache<UInt160, ContractState> IPersistence.Contracts => GetContracts();
DataCache<StorageKey, StorageItem> IPersistence.Storages => GetStorages();
DataCache<UInt32Wrapper, HeaderHashList> IPersistence.HeaderHashList => GetHeaderHashList();
MetaDataCache<NextValidatorsState> IPersistence.NextValidators => GetNextValidators();
MetaDataCache<HashIndexState> IPersistence.BlockHashIndex => GetBlockHashIndex();
MetaDataCache<HashIndexState> IPersistence.HeaderHashIndex => GetHeaderHashIndex();

Expand All @@ -21,7 +20,6 @@ public abstract class Store : IPersistence
public abstract DataCache<UInt160, ContractState> GetContracts();
public abstract DataCache<StorageKey, StorageItem> GetStorages();
public abstract DataCache<UInt32Wrapper, HeaderHashList> GetHeaderHashList();
public abstract MetaDataCache<NextValidatorsState> GetNextValidators();
public abstract MetaDataCache<HashIndexState> GetBlockHashIndex();
public abstract MetaDataCache<HashIndexState> GetHeaderHashIndex();
public abstract void Put(byte prefix, byte[] key, byte[] value);
Expand Down
16 changes: 14 additions & 2 deletions neo/SmartContract/Native/NativeContract.cs
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,13 @@ internal bool Invoke(ApplicationEngine engine)

protected virtual StackItem Main(ApplicationEngine engine, string operation, VMArray args)
{
if (operation == "supportedStandards")
return SupportedStandards.Select(p => (StackItem)p).ToList();
switch (operation)
{
case "onPersist":
return OnPersist(engine);
case "supportedStandards":
return SupportedStandards.Select(p => (StackItem)p).ToList();
}
throw new NotSupportedException();
}

Expand All @@ -79,6 +84,13 @@ internal virtual bool Initialize(ApplicationEngine engine)
return true;
}

protected virtual bool OnPersist(ApplicationEngine engine)
{
if (engine.Trigger != TriggerType.System)
throw new InvalidOperationException();
return true;
}

public ApplicationEngine TestCall(string operation, params object[] args)
{
using (ScriptBuilder sb = new ScriptBuilder())
Expand Down
23 changes: 7 additions & 16 deletions neo/SmartContract/Native/Tokens/GasToken.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,27 +24,18 @@ internal GasToken()

protected override StackItem Main(ApplicationEngine engine, string operation, VMArray args)
{
switch (operation)
{
case "distributeFees":
return DistributeFees(engine);
case "getSysFeeAmount":
return GetSysFeeAmount(engine, (uint)args[0].GetBigInteger());
default:
return base.Main(engine, operation, args);
}
if (operation == "getSysFeeAmount")
return GetSysFeeAmount(engine, (uint)args[0].GetBigInteger());
else
return base.Main(engine, operation, args);
}

private bool DistributeFees(ApplicationEngine engine)
protected override bool OnPersist(ApplicationEngine engine)
{
if (engine.Trigger != TriggerType.System) throw new InvalidOperationException();
if (!base.OnPersist(engine)) return false;
foreach (Transaction tx in engine.Snapshot.PersistingBlock.Transactions)
Burn(engine, tx.Sender, tx.Gas + tx.NetworkFee);
ECPoint[] validators;
if (engine.Snapshot.PersistingBlock.Index > 1)
validators = engine.Snapshot.NextValidators.Get().Validators;
else
validators = Blockchain.StandbyValidators;
ECPoint[] validators = NEO.GetNextBlockValidators(engine.Snapshot);
UInt160 primary = Contract.CreateSignatureRedeemScript(validators[engine.Snapshot.PersistingBlock.ConsensusData.PrimaryIndex]).ToScriptHash();
Mint(engine, primary, engine.Snapshot.PersistingBlock.Transactions.Sum(p => p.NetworkFee));
BigInteger sys_fee = GetSysFeeAmount(engine, engine.Snapshot.PersistingBlock.Index - 1) + engine.Snapshot.PersistingBlock.Transactions.Sum(p => p.Gas);
Expand Down
Loading