예제 #1
0
		public void Load(BitcoinStream stream)
		{
			using(@lock.LockWrite())
			{
				try
				{
					int height = 0;
					while(true)
					{
						uint256 id = null;
						stream.ReadWrite<uint256>(ref id);
						BlockHeader header = null;
						stream.ReadWrite(ref header);
						if(height == 0)
						{
							_BlocksByHeight.Clear();
							_BlocksById.Clear();
							_Tip = null;
							SetTipNoLock(new ChainedBlock(header, 0));
						}
						else
							SetTipNoLock(new ChainedBlock(header, id, Tip));
						height++;
					}
				}
				catch(EndOfStreamException)
				{
				}
			}
		}
예제 #2
0
		public void ReadWrite(BitcoinStream stream)
		{
			stream.ReadWrite(ref _chainHeight);
			stream.ReadWrite(ref _chainTipHash);
			stream.ReadWrite(ref _bitmap);
			stream.ReadWrite(ref _outputs);
		}
예제 #3
0
		private bool ReadData(byte[] data)
		{
			try
			{
				BitcoinStream stream = new BitcoinStream(data);
				ushort marker = 0;
				stream.ReadWrite(ref marker);
				if(marker != Tag)
					return false;
				stream.ReadWrite(ref _Version);
				if(_Version != 1)
					return false;

				ulong quantityCount = 0;
				stream.ReadWriteAsVarInt(ref quantityCount);
				Quantities = new ulong[quantityCount];

				for(ulong i = 0 ; i < quantityCount ; i++)
				{
					Quantities[i] = ReadLEB128(stream);
					if(Quantities[i] > MAX_QUANTITY)
						return false;
				}

				stream.ReadWriteAsVarString(ref _Metadata);
				if(stream.Inner.Position != data.Length)
					return false;
				return true;
			}
			catch(Exception)
			{
				return false;
			}
		}
예제 #4
0
		private bool ReadScript(Script script)
		{
			try
			{
				var data = TxNullDataTemplate.Instance.ExtractScriptPubKeyParameters(script);
				if(data == null)
					return false;
				BitcoinStream stream = new BitcoinStream(data);
				ushort marker = 0;
				stream.ReadWrite(ref marker);
				if(marker != Tag)
					return false;
				stream.ReadWrite(ref _Version);
				if(_Version != 1)
					return false;

				ulong quantityCount = 0;
				stream.ReadWriteAsVarInt(ref quantityCount);
				Quantities = new ulong[quantityCount];

				for(ulong i = 0 ; i < quantityCount ; i++)
				{
					Quantities[i] = ReadLEB128(stream);
					if(Quantities[i] > MAX_QUANTITY)
						return false;
				}

				stream.ReadWriteAsVarString(ref _Metadata);
				return true;
			}
			catch(Exception)
			{
				return false;
			}
		}
예제 #5
0
			public void ReadWrite(BitcoinStream stream)
			{
				stream.ReadWrite(ref _Address);
				stream.ReadWrite(ref source);
				stream.ReadWrite(ref nLastSuccess);
				stream.ReadWrite(ref nAttempts);

			}
예제 #6
0
 public void ReadWrite(BitcoinStream stream)
 {
     var len = new VarInt((ulong)_Bytes.Length);
      stream.ReadWrite(ref len);
     if(!stream.Serializing)
         _Bytes = new byte[len.ToLong()];
     stream.ReadWrite(ref _Bytes);
 }
예제 #7
0
파일: Message.cs 프로젝트: n1rvana/NBitcoin
		public void ReadWrite(BitcoinStream stream)
		{
			if(Payload == null && stream.Serializing)
				throw new InvalidOperationException("Payload not affected");
			if(stream.Serializing || (!stream.Serializing && !_SkipMagic))
				stream.ReadWrite(ref magic);
			stream.ReadWrite(ref command);
			int length = 0;
			uint checksum = 0;
			bool hasChecksum = false;
			byte[] payloadBytes = stream.Serializing ? GetPayloadBytes(stream.ProtocolVersion, out length) : null;
			length = payloadBytes == null ? 0 : length;
			stream.ReadWrite(ref length);

			if(stream.ProtocolVersion >= ProtocolVersion.MEMPOOL_GD_VERSION)
			{
				if(stream.Serializing)
					checksum = Hashes.Hash256(payloadBytes, 0, length).GetLow32();
				stream.ReadWrite(ref checksum);
				hasChecksum = true;
			}
			if(stream.Serializing)
			{
				stream.ReadWrite(ref payloadBytes, 0, length);
			}
			else
			{
				if(length > 0x02000000) //MAX_SIZE 0x02000000 Serialize.h
				{
					throw new FormatException("Message payload too big ( > 0x02000000 bytes)");
				}

				payloadBytes = _Buffer == null || _Buffer.Length < length ? new byte[length] : _Buffer;
				stream.ReadWrite(ref payloadBytes, 0, length);

				if(hasChecksum)
				{
					if(!VerifyChecksum(checksum, payloadBytes, length))
					{
						if(NodeServerTrace.Trace.Switch.ShouldTrace(TraceEventType.Verbose))
							NodeServerTrace.Trace.TraceEvent(TraceEventType.Verbose, 0, "Invalid message checksum bytes");
						throw new FormatException("Message checksum invalid");
					}
				}
				BitcoinStream payloadStream = new BitcoinStream(payloadBytes);
				payloadStream.CopyParameters(stream);

				var payloadType = PayloadAttribute.GetCommandType(Command);
				var unknown = payloadType == typeof(UnknowPayload);
				if(unknown)
					NodeServerTrace.Trace.TraceEvent(TraceEventType.Warning, 0, "Unknown command received : " + Command);
				object payload = _PayloadObject;
				payloadStream.ReadWrite(payloadType, ref payload);
				if(unknown)
					((UnknowPayload)payload)._Command = Command;
				Payload = (Payload)payload;
			}
		}
예제 #8
0
		public void ReadWrite(BitcoinStream stream)
		{
			 var len = new VarInt((ulong)_Bytes.Length);
			 stream.ReadWrite(ref len);
			 if(!stream.Serializing)
			 {
				 if(len.ToLong() > (uint)stream.MaxArraySize)
					 throw new ArgumentOutOfRangeException("Array size not big");
				 _Bytes = new byte[len.ToLong()];
			 }
			stream.ReadWrite(ref _Bytes);
		}
예제 #9
0
			public void ReadWrite(BitcoinStream stream)
			{
				if(stream.Serializing)
				{
					var b = Value.ToBytes();
					stream.ReadWrite(ref b);
				}
				else
				{
					byte[] b = new byte[WIDTH_BYTE];
					stream.ReadWrite(ref b);
					_Value = new uint256(b);
				}
			}
예제 #10
0
		public override void ReadWriteCore(BitcoinStream stream)
		{
			if(stream.Serializing)
			{
				var heardersOff = headers.Select(h => new BlockHeaderWithTxCount(h)).ToList();
				stream.ReadWrite(ref heardersOff);
			}
			else
			{
				headers.Clear();
				List<BlockHeaderWithTxCount> headersOff = new List<BlockHeaderWithTxCount>();
				stream.ReadWrite(ref headersOff);
				headers.AddRange(headersOff.Select(h => h._Header));
			}
		}
예제 #11
0
		public void ReadWrite(BitcoinStream stream)
		{
			stream.ReadWrite(ref _OutPoint);
			if(stream.Serializing)
			{
				TxOutCompressor compressor = new TxOutCompressor(_Out);
				stream.ReadWrite(ref compressor);
			}
			else
			{
				TxOutCompressor compressor = new TxOutCompressor();
				stream.ReadWrite(ref compressor);
				_Out = compressor.TxOut;
			}
		}
예제 #12
0
		public void bloom_create_insert_serialize()
		{
			BloomFilter filter = new BloomFilter(3, 0.01, 0, BloomFlags.UPDATE_ALL);

			filter.Insert(ParseHex("99108ad8ed9bb6274d3980bab5a85c048f0950c8"));
			Assert.True(filter.Contains(ParseHex("99108ad8ed9bb6274d3980bab5a85c048f0950c8")), "BloomFilter doesn't contain just-inserted object!");
			// One bit different in first byte
			Assert.True(!filter.Contains(ParseHex("19108ad8ed9bb6274d3980bab5a85c048f0950c8")), "BloomFilter contains something it shouldn't!");

			filter.Insert(ParseHex("b5a2c786d9ef4658287ced5914b37a1b4aa32eee"));
			Assert.True(filter.Contains(ParseHex("b5a2c786d9ef4658287ced5914b37a1b4aa32eee")), "BloomFilter doesn't contain just-inserted object (2)!");

			filter.Insert(ParseHex("b9300670b4c5366e95b2699e8b18bc75e5f729c5"));
			Assert.True(filter.Contains(ParseHex("b9300670b4c5366e95b2699e8b18bc75e5f729c5")), "BloomFilter doesn't contain just-inserted object (3)!");


			var ms = new MemoryStream();
			BitcoinStream bitcoinStream = new BitcoinStream(ms, true);
			bitcoinStream.ReadWrite(filter);

			var expected = ParseHex("03614e9b050000000000000001");


			AssertEx.CollectionEquals(expected, ms.ToArray());
		}
예제 #13
0
 public override void ReadWriteCore(BitcoinStream stream)
 {
     var old = stream.MaxArraySize;
     stream.MaxArraySize = 5000;
     stream.ReadWrite(ref inventory);
     stream.MaxArraySize = old;
 }
예제 #14
0
		public void uitnSerializationTests()
		{
			MemoryStream ms = new MemoryStream();
			BitcoinStream stream = new BitcoinStream(ms, true);

			var v = new uint256("00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
			var vless = new uint256("00000000fffffffffffffffffffffffffffffffffffffffffffffffffffffffe");
			var vplus = new uint256("00000001ffffffffffffffffffffffffffffffffffffffffffffffffffffffff");

			stream.ReadWrite(ref v);
			Assert.NotNull(v);

			ms.Position = 0;
			stream = new BitcoinStream(ms, false);

			uint256 v2 = uint256.Zero;
			stream.ReadWrite(ref v2);
			Assert.Equal(v, v2);

			v2 = null;
			ms.Position = 0;
			stream.ReadWrite(ref v2);
			Assert.Equal(v, v2);

			List<uint256> vs = new List<uint256>()
			{
				v,vless,vplus
			};

			ms = new MemoryStream();
			stream = new BitcoinStream(ms, true);
			stream.ReadWrite(ref vs);
			Assert.True(vs.Count == 3);

			ms.Position = 0;
			stream = new BitcoinStream(ms, false);
			List<uint256> vs2 = new List<uint256>();
			stream.ReadWrite(ref vs2);
			Assert.True(vs2.SequenceEqual(vs));

			ms.Position = 0;
			vs2 = null;
			stream.ReadWrite(ref vs2);
			Assert.True(vs2.SequenceEqual(vs));
		}
예제 #15
0
		public void ReadWrite(BitcoinStream stream)
		{
			stream.ReadWriteAsVarInt(ref _Index);
			if(stream.Serializing)
			{
				byte[] assetId = Asset.Id.ToBytes();
				stream.ReadWrite(ref assetId);
				long quantity = Asset.Quantity;
				stream.ReadWrite(ref quantity);
			}
			else
			{
				byte[] assetId = new byte[20];
				stream.ReadWrite(ref assetId);
				long quantity = 0;
				stream.ReadWrite(ref quantity);
				Asset = new AssetMoney(new AssetId(assetId), quantity);
			}
		}
예제 #16
0
파일: VarInt.cs 프로젝트: crowar/NBitcoin
		public void ReadWrite(BitcoinStream stream)
		{
			if(stream.Serializing)
			{
				ulong n = _Value;
				byte[] tmp = new byte[(_Size * 8 + 6) / 7];
				int len = 0;
				while(true)
				{
					byte a = (byte)(n & 0x7F);
					byte b = (byte)(len != 0 ? 0x80 : 0x00);
					tmp[len] = (byte)(a | b);
					if(n <= 0x7F)
						break;
					n = (n >> 7) - 1;
					len++;
				}
				do
				{
					byte b = tmp[len];
					stream.ReadWrite(ref b);
				} while(len-- != 0);
			}
			else
			{
				ulong n = 0;
				while(true)
				{
					byte chData = 0;
					stream.ReadWrite(ref chData);
					ulong a = (n << 7);
					byte b = (byte)(chData & 0x7F);
					n = (a | b);
					if((chData & 0x80) != 0)
						n++;
					else
						break;
				}
				_Value = n;
			}
		}
예제 #17
0
		// serialization implementation
		#region IBitcoinSerializable Members

		public void ReadWrite(BitcoinStream stream)
		{
			stream.ReadWrite(ref _TransactionCount);
			stream.ReadWrite(ref _Hashes);
			byte[] vBytes = null;
			if(!stream.Serializing)
			{
				stream.ReadWriteAsVarString(ref vBytes);
				BitWriter writer = new BitWriter();
				for(int p = 0 ; p < vBytes.Length * 8 ; p++)
					writer.Write((vBytes[p / 8] & (1 << (p % 8))) != 0);
				_Flags = writer.ToBitArray();
			}
			else
			{
				vBytes = new byte[(_Flags.Length + 7) / 8];
				for(int p = 0 ; p < _Flags.Length ; p++)
					vBytes[p / 8] |= (byte)(ToByte(_Flags.Get(p)) << (p % 8));
				stream.ReadWriteAsVarString(ref vBytes);
			}
		}
예제 #18
0
		public override void ReadWriteCore(BitcoinStream stream)
		{
			stream.ReadWrite(ref _BlockId);
			ulong indexes_size = (ulong)_Indices.Count;
			stream.ReadWriteAsVarInt(ref indexes_size);
			if(!stream.Serializing)
			{
				ulong i = 0;
				ulong indicesCount = 0;
				while((ulong)_Indices.Count < indexes_size)
				{
					indicesCount = Math.Min(1000UL + (ulong)indicesCount, (ulong)indexes_size);
					for(; i < indicesCount; i++)
					{
						ulong index = 0;
						stream.ReadWriteAsVarInt(ref index);
						if(index > Int32.MaxValue)
							throw new FormatException("indexes overflowed 31-bits");
						_Indices.Add((int)index);
					}
				}

				int offset = 0;
				for(var ii = 0; ii < _Indices.Count; ii++)
				{
					if((ulong)(_Indices[ii]) + (ulong)(offset) > Int32.MaxValue)
						throw new FormatException("indexes overflowed 31-bits");
					_Indices[ii] = _Indices[ii] + offset;
					offset = _Indices[ii] + 1;
				}
			}
			else
			{
				for(var i = 0; i < _Indices.Count; i++)
				{
					int index = _Indices[i] - (i == 0 ? 0 : (_Indices[i - 1] + 1));					
					stream.ReadWrite(ref index);
				}
			}
		}
예제 #19
0
		private AlertPayload[] ReadAlerts()
		{
			List<AlertPayload> alerts = new List<AlertPayload>();
			using(var fs = File.OpenRead("data/alertTests.raw"))
			{
				BitcoinStream stream = new BitcoinStream(fs, false);
				while(stream.Inner.Position != stream.Inner.Length)
				{
					AlertPayload payload = null;
					stream.ReadWrite(ref payload);
					alerts.Add(payload);
				}
			}
			return alerts.ToArray();
		}
예제 #20
0
        public void bloom_create_insert_key()
        {
            string strSecret = "5Kg1gnAjaLfKiwhhPpGS3QfRg2m6awQvaj98JCZBZQ5SuS2F15C";
            BitcoinSecret vchSecret = Network.Main.CreateBitcoinSecret(strSecret);
            var pubkey = vchSecret.Key.PubKey;

            BloomFilter filter = new BloomFilter(2, 0.001, 0, BloomFlags.UPDATE_ALL);
            filter.Insert(pubkey.ToBytes());
            filter.Insert(pubkey.ID.ToBytes());

            var ms = new MemoryStream();
            BitcoinStream bitcoinStream = new BitcoinStream(ms, true);
            bitcoinStream.ReadWrite(filter);

            var expected = ParseHex("038fc16b080000000000000001");

            AssertEx.CollectionEquals(expected, ms.ToArray());
        }
예제 #21
0
		private Transaction AssertClone(Transaction before)
		{
			Transaction after = before.Clone();
			Transaction after2 = null;

			MemoryStream ms = new MemoryStream();
			BitcoinStream stream = new BitcoinStream(ms, true);
			stream.TransactionOptions = TransactionOptions.None;
			stream.ReadWrite(before);

			ms.Position = 0;

			stream = new BitcoinStream(ms, false);
			stream.TransactionOptions = TransactionOptions.Witness;
			stream.ReadWrite(ref after2);

			Assert.Equal(after2.GetHash(), after.GetHash());
			Assert.Equal(before.GetHash(), after.GetHash());

			return after;
		}
예제 #22
0
        public void ReadWrite(BitcoinStream stream)
        {
            lock (cs)
            {
                Check();
                if (!stream.Serializing)
                {
                    Clear();
                }
                stream.ReadWrite(ref nVersion);
                stream.ReadWrite(ref nKeySize);
                if (!stream.Serializing && nKeySize != 32)
                {
                    throw new FormatException("Incorrect keysize in addrman deserialization");
                }
                stream.ReadWrite(ref nKey);
                stream.ReadWrite(ref nNew);
                stream.ReadWrite(ref nTried);

                int nUBuckets = ADDRMAN_NEW_BUCKET_COUNT ^ (1 << 30);
                stream.ReadWrite(ref nUBuckets);
                if (nVersion != 0)
                {
                    nUBuckets ^= (1 << 30);
                }
                if (!stream.Serializing)
                {
                    // Deserialize entries from the new table.
                    for (int n = 0; n < nNew; n++)
                    {
                    }

                    nIdCount = nNew;

                    // Deserialize entries from the tried table.
                    int nLost = 0;
                    for (int n = 0; n < nTried; n++)
                    {
                    }

                    nTried -= nLost;

                    // Deserialize positions in the new table (if possible).
                    for (int bucket = 0; bucket < nUBuckets; bucket++)
                    {
                        int nSize = 0;
                        stream.ReadWrite(ref nSize);
                        for (int n = 0; n < nSize; n++)
                        {
                            int nIndex = 0;
                            stream.ReadWrite(ref nIndex);
                            if (nIndex >= 0 && nIndex < nNew)
                            {
                                AddressInfo info        = mapInfo[nIndex];
                                int         nUBucketPos = info.GetBucketPosition(nKey, true, bucket);
                                if (nVersion == 1 && nUBuckets == ADDRMAN_NEW_BUCKET_COUNT && vvNew[bucket, nUBucketPos] == -1 && info.nRefCount < ADDRMAN_NEW_BUCKETS_PER_ADDRESS)
                                {
                                    info.nRefCount++;
                                    vvNew[bucket, nUBucketPos] = nIndex;
                                }
                            }
                        }
                    }

                    // Prune new entries with refcount 0 (as a result of collisions).
                    int nLostUnk = 0;
                    foreach (var kv in mapInfo.ToList())
                    {
                        if (kv.Value.fInTried == false && kv.Value.nRefCount == 0)
                        {
                            Delete(kv.Key);
                            nLostUnk++;
                        }
                    }
                }
                else
                {
                    Dictionary <int, int> mapUnkIds = new Dictionary <int, int>();
                    int nIds = 0;
                    foreach (var kv in mapInfo)
                    {
                        mapUnkIds[kv.Key] = nIds;
                        AddressInfo info = kv.Value;
                        if (info.nRefCount != 0)
                        {
                            assert(nIds != nNew);                             // this means nNew was wrong, oh ow
                            info.ReadWrite(stream);
                            nIds++;
                        }
                    }
                    nIds = 0;
                    foreach (var kv in mapInfo)
                    {
                        AddressInfo info = kv.Value;
                        if (info.fInTried)
                        {
                            assert(nIds != nTried);                             // this means nTried was wrong, oh ow
                            info.ReadWrite(stream);
                            nIds++;
                        }
                    }

                    for (int bucket = 0; bucket < ADDRMAN_NEW_BUCKET_COUNT; bucket++)
                    {
                        int nSize = 0;
                        for (int i = 0; i < ADDRMAN_BUCKET_SIZE; i++)
                        {
                            if (vvNew[bucket, i] != -1)
                            {
                                nSize++;
                            }
                        }
                        stream.ReadWrite(ref nSize);
                        for (int i = 0; i < ADDRMAN_BUCKET_SIZE; i++)
                        {
                            if (vvNew[bucket, i] != -1)
                            {
                                int nIndex = mapUnkIds[vvNew[bucket, i]];
                                stream.ReadWrite(ref nIndex);
                            }
                        }
                    }
                }
                Check();
            }
        }
예제 #23
0
 public override void ReadWriteCore(BitcoinStream stream)
 {
     stream.ReadWrite(ref this.addr_list);
 }
예제 #24
0
 public void ReadWrite(BitcoinStream stream)
 {
     stream.ReadWrite(ref _PreviousBlockHash);
     stream.ReadWrite(ref _TransactionsToRemove);
     stream.ReadWrite(ref _OutputsToRestore);
 }
예제 #25
0
 public override void ReadWriteCore(BitcoinStream stream)
 {
     stream.ReadWrite(ref this.nonce);
 }
예제 #26
0
		public override void ReadWriteCore(BitcoinStream stream)
		{
			stream.ReadWrite(ref type);
			stream.ReadWrite(ref hash);
		}
예제 #27
0
        protected virtual void BuildCoinbase()
        {
            // generate script parts
            var sigScriptInitial      = GenerateScriptSigInitial();
            var sigScriptInitialBytes = sigScriptInitial.ToBytes();

            var sigScriptLength = (uint)(
                sigScriptInitial.Length +
                extraNoncePlaceHolderLength +
                scriptSigFinalBytes.Length);

            // output transaction
            txOut = CreateOutputTransaction();

            // build coinbase initial
            using (var stream = new MemoryStream())
            {
                var bs = new BitcoinStream(stream, true);

                // version
                bs.ReadWrite(ref txVersion);

                // timestamp for POS coins
                if (isPoS)
                {
                    var timestamp = BlockTemplate.CurTime;
                    bs.ReadWrite(ref timestamp);
                }

                // serialize (simulated) input transaction
                bs.ReadWriteAsVarInt(ref txInputCount);
                bs.ReadWrite(ref sha256Empty);
                bs.ReadWrite(ref txInPrevOutIndex);

                // signature script initial part
                bs.ReadWriteAsVarInt(ref sigScriptLength);
                bs.ReadWrite(ref sigScriptInitialBytes);

                // done
                coinbaseInitial    = stream.ToArray();
                coinbaseInitialHex = coinbaseInitial.ToHexString();
            }

            // build coinbase final
            using (var stream = new MemoryStream())
            {
                var bs = new BitcoinStream(stream, true);

                // signature script final part
                bs.ReadWrite(ref scriptSigFinalBytes);

                // tx in sequence
                bs.ReadWrite(ref txInSequence);

                // serialize output transaction
                var txOutBytes = SerializeOutputTransaction(txOut);
                bs.ReadWrite(ref txOutBytes);

                // misc
                bs.ReadWrite(ref txLockTime);

                // done
                coinbaseFinal    = stream.ToArray();
                coinbaseFinalHex = coinbaseFinal.ToHexString();
            }
        }
예제 #28
0
 public override void ReadWriteCore(BitcoinStream stream)
 {
     stream.ReadWrite(ref version);
     stream.ReadWrite(ref blockLocators);
     stream.ReadWrite(ref hashStop);
 }
예제 #29
0
        // Stratis kernel protocol
        // coinstake must meet hash target according to the protocol:
        // kernel (input 0) must meet the formula
        //     hash(nStakeModifier + txPrev.block.nTime + txPrev.nTime + txPrev.vout.hash + txPrev.vout.n + nTime) < bnTarget * nWeight
        // this ensures that the chance of getting a coinstake is proportional to the
        // amount of coins one owns.
        // The reason this hash is chosen is the following:
        //   nStakeModifier: scrambles computation to make it very difficult to precompute
        //                   future proof-of-stake
        //   txPrev.block.nTime: prevent nodes from guessing a good timestamp to
        //                       generate transaction for future advantage,
        //                       obsolete since v3
        //   txPrev.nTime: slightly scrambles computation
        //   txPrev.vout.hash: hash of txPrev, to reduce the chance of nodes
        //                     generating coinstake at the same time
        //   txPrev.vout.n: output number of txPrev, to reduce the chance of nodes
        //                  generating coinstake at the same time
        //   nTime: current timestamp
        //   block/tx hash should not be used here as they can be generated in vast
        //   quantities so as to generate blocks faster, degrading the system back into
        //   a proof-of-work situation.
        //
        private static bool CheckStakeKernelHashV2(ChainedBlock pindexPrev, uint nBits, uint nTimeBlockFrom,
                                                   Transaction txPrev, OutPoint prevout, uint nTimeTx, out uint256 hashProofOfStake, out uint256 targetProofOfStake, bool fPrintProofOfStake)
        {
            targetProofOfStake = null; hashProofOfStake = null;

            if (nTimeTx < txPrev.Time)        // Transaction timestamp violation
            {
                return(false);                //error("CheckStakeKernelHash() : nTime violation");
            }
            // Base target
            var bnTarget = new Target(nBits).ToBigInteger();

            // Weighted target
            var nValueIn = txPrev.Outputs[prevout.N].Value.Satoshi;
            var bnWeight = BigInteger.ValueOf(nValueIn);

            bnTarget = bnTarget.Multiply(bnWeight);

            // todo: investigate this issue, is the convertion to uint256 similar to the c++ implementation
            //targetProofOfStake = Target.ToUInt256(bnTarget);

            var     nStakeModifier       = pindexPrev.Header.PosParameters.StakeModifier;
            uint256 bnStakeModifierV2    = pindexPrev.Header.PosParameters.StakeModifierV2;
            int     nStakeModifierHeight = pindexPrev.Height;
            var     nStakeModifierTime   = pindexPrev.Header.Time;

            // Calculate hash
            using (var ms = new MemoryStream())
            {
                var serializer = new BitcoinStream(ms, true);
                if (IsProtocolV3((int)nTimeTx))
                {
                    serializer.ReadWrite(bnStakeModifierV2);
                }
                else
                {
                    serializer.ReadWrite(nStakeModifier);
                    serializer.ReadWrite(nTimeBlockFrom);
                }

                serializer.ReadWrite(txPrev.Time);
                serializer.ReadWrite(prevout.Hash);
                serializer.ReadWrite(prevout.N);
                serializer.ReadWrite(nTimeTx);

                hashProofOfStake = Hashes.Hash256(ms.ToArray());
            }

            if (fPrintProofOfStake)
            {
                //LogPrintf("CheckStakeKernelHash() : using modifier 0x%016x at height=%d timestamp=%s for block from timestamp=%s\n",
                //	nStakeModifier, nStakeModifierHeight,
                //	DateTimeStrFormat(nStakeModifierTime),

                //	DateTimeStrFormat(nTimeBlockFrom));

                //LogPrintf("CheckStakeKernelHash() : check modifier=0x%016x nTimeBlockFrom=%u nTimeTxPrev=%u nPrevout=%u nTimeTx=%u hashProof=%s\n",
                //	nStakeModifier,
                //	nTimeBlockFrom, txPrev.nTime, prevout.n, nTimeTx,
                //	hashProofOfStake.ToString());
            }

            // Now check if proof-of-stake hash meets target protocol
            var hashProofOfStakeTarget = new BigInteger(hashProofOfStake.ToBytes(false));

            if (hashProofOfStakeTarget.CompareTo(bnTarget) > 0)
            {
                return(false);
            }


            //  if (fDebug && !fPrintProofOfStake)
            //  {
            //		LogPrintf("CheckStakeKernelHash() : using modifier 0x%016x at height=%d timestamp=%s for block from timestamp=%s\n",
            //		nStakeModifier, nStakeModifierHeight,
            //		DateTimeStrFormat(nStakeModifierTime),

            //		DateTimeStrFormat(nTimeBlockFrom));

            //		LogPrintf("CheckStakeKernelHash() : pass modifier=0x%016x nTimeBlockFrom=%u nTimeTxPrev=%u nPrevout=%u nTimeTx=%u hashProof=%s\n",
            //		nStakeModifier,
            //		nTimeBlockFrom, txPrev.nTime, prevout.n, nTimeTx,
            //		hashProofOfStake.ToString());
            //  }

            return(true);
        }
예제 #30
0
 public override void ReadWrite(BitcoinStream stream)
 {
     base.ReadWrite(stream);
     stream.ReadWrite(ref this.Data);
 }
예제 #31
0
 protected override void ReadWriteHashingStream(BitcoinStream stream)
 {
     base.ReadWriteHashingStream(stream);
     stream.ReadWrite(ref this.Data);
 }
예제 #32
0
 public void ReadWrite(BitcoinStream stream)
 {
     stream.ReadWrite(ref this.version);
     stream.ReadWrite(ref this.height);
     stream.ReadWrite(ref this.txOut);
 }
예제 #33
0
        public void ReadWrite(BitcoinStream stream)
        {
            if (Payload == null && stream.Serializing)
            {
                throw new InvalidOperationException("Payload not affected");
            }
            if (stream.Serializing || (!stream.Serializing && !_SkipMagic))
            {
                stream.ReadWrite(ref magic);
            }

            stream.ReadWrite(ref command);
            int  length      = 0;
            uint checksum    = 0;
            bool hasChecksum = false;

            byte[] payloadBytes = stream.Serializing ? GetPayloadBytes(stream, out length) : null;
            length = payloadBytes == null ? 0 : length;
            stream.ReadWrite(ref length);

            if (stream.ProtocolCapabilities.SupportCheckSum)
            {
                if (stream.Serializing)
                {
                    checksum = stream.ProtocolCapabilities.CalculateChecksum(payloadBytes, 0, length);
                }
                stream.ReadWrite(ref checksum);
                hasChecksum = true;
            }
            if (stream.Serializing)
            {
                stream.ReadWrite(ref payloadBytes, 0, length);
            }
            else
            {
                if (length > 0x02000000)                //MAX_SIZE 0x02000000 Serialize.h
                {
                    throw new FormatException("Message payload too big ( > 0x02000000 bytes)");
                }

                payloadBytes = _Buffer == null || _Buffer.Length < length ? new byte[length] : _Buffer;
                stream.ReadWrite(ref payloadBytes, 0, length);

                if (hasChecksum)
                {
                    if (stream.ProtocolCapabilities.CalculateChecksum(payloadBytes, 0, length) != checksum)
                    {
                        if (NodeServerTrace.Trace.Switch.ShouldTrace(TraceEventType.Verbose))
                        {
                            NodeServerTrace.Trace.TraceEvent(TraceEventType.Verbose, 0, "Invalid message checksum bytes");
                        }
                        throw new FormatException("Message checksum invalid");
                    }
                }
                BitcoinStream payloadStream = new BitcoinStream(payloadBytes);
                payloadStream.CopyParameters(stream);

                var payloadType = PayloadAttribute.GetCommandType(Command);
                var unknown     = payloadType == typeof(UnknowPayload);
                if (unknown)
                {
                    NodeServerTrace.Trace.TraceEvent(TraceEventType.Warning, 0, "Unknown command received : " + Command);
                }
                object payload = _PayloadObject;
                payloadStream.ReadWrite(payloadType, ref payload);
                if (unknown)
                {
                    ((UnknowPayload)payload)._Command = Command;
                }
                Payload = (Payload)payload;
            }
        }
예제 #34
0
            private void DeserializeTxn(BitcoinStream stream, bool witSupported)
            {
                byte flags = 0;

                UInt32 nVersionTemp = 0;

                stream.ReadWrite(ref nVersionTemp);

                // POS time stamp
                uint nTimeTemp = 0;

                stream.ReadWrite(ref nTimeTemp);

                TxInList  vinTemp  = new TxInList();
                TxOutList voutTemp = new TxOutList();

                /* Try to read the vin. In case the dummy is there, this will be read as an empty vector. */
                stream.ReadWrite <TxInList, TxIn>(ref vinTemp);

                var hasNoDummy = (nVersionTemp & NoDummyInput) != 0 && vinTemp.Count == 0;

                if (witSupported && hasNoDummy)
                {
                    nVersionTemp = nVersionTemp & ~NoDummyInput;
                }

                if (vinTemp.Count == 0 && witSupported && !hasNoDummy)
                {
                    /* We read a dummy or an empty vin. */
                    stream.ReadWrite(ref flags);
                    if (flags != 0)
                    {
                        /* Assume we read a dummy and a flag. */
                        stream.ReadWrite <TxInList, TxIn>(ref vinTemp);
                        vinTemp.Transaction = this;
                        stream.ReadWrite <TxOutList, TxOut>(ref voutTemp);
                        voutTemp.Transaction = this;
                    }
                    else
                    {
                        /* Assume read a transaction without output. */
                        voutTemp             = new TxOutList();
                        voutTemp.Transaction = this;
                    }
                }
                else
                {
                    /* We read a non-empty vin. Assume a normal vout follows. */
                    stream.ReadWrite <TxOutList, TxOut>(ref voutTemp);
                    voutTemp.Transaction = this;
                }
                if (((flags & 1) != 0) && witSupported)
                {
                    /* The witness flag is present, and we support witnesses. */
                    flags ^= 1;
                    BitcoinplusWitness wit = new BitcoinplusWitness(vinTemp);
                    wit.ReadWrite(stream);
                }
                if (flags != 0)
                {
                    /* Unknown flag in the serialization */
                    throw new FormatException("Unknown transaction optional data");
                }
                LockTime lockTimeTemp = 0;

                stream.ReadWriteStruct(ref lockTimeTemp);

                this.Version = nVersionTemp;
                this.Time    = nTimeTemp; // POS Timestamp
                vinTemp.ForEach(i => this.Inputs.Add(i));
                voutTemp.ForEach(i => this.Outputs.Add(i));
                this.LockTime = lockTimeTemp;
            }
예제 #35
0
		public void ReadWrite(BitcoinStream stream)
		{
			if(stream.Serializing)
			{
				uint nMaskSize = 0, nMaskCode = 0;
				CalcMaskSize(ref nMaskSize, ref nMaskCode);
				bool fFirst = vout.Count > 0 && !vout[0].IsNull;
				bool fSecond = vout.Count > 1 && !vout[1].IsNull;
				uint nCode = unchecked((uint)(8 * (nMaskCode - (fFirst || fSecond ? 0 : 1)) + (fCoinBase ? 1 : 0) + (fFirst ? 2 : 0) + (fSecond ? 4 : 0)));
				// version
				stream.ReadWriteAsVarInt(ref nVersion);
				// size of header code
				stream.ReadWriteAsVarInt(ref nCode);
				// spentness bitmask
				for(uint b = 0 ; b < nMaskSize ; b++)
				{
					byte chAvail = 0;
					for(uint i = 0 ; i < 8 && 2 + b * 8 + i < vout.Count ; i++)
						if(!vout[2 + (int)b * 8 + (int)i].IsNull)
							chAvail |= (byte)(1 << (int)i);
					stream.ReadWrite(ref chAvail);
				}

				// txouts themself
				for(uint i = 0 ; i < vout.Count ; i++)
				{
					if(!vout[(int)i].IsNull)
					{
						var compressedTx = new TxOutCompressor(vout[(int)i]);
						stream.ReadWrite(ref compressedTx);
					}
				}
				// coinbase height
				stream.ReadWriteAsVarInt(ref nHeight);
			}
			else
			{
				uint nCode = 0;
				// version
				stream.ReadWriteAsVarInt(ref nVersion);
				//// header code
				stream.ReadWriteAsVarInt(ref nCode);
				fCoinBase = (nCode & 1) != 0;
				List<bool> vAvail = new List<bool>() { false, false };
				vAvail[0] = (nCode & 2) != 0;
				vAvail[1] = (nCode & 4) != 0;
				uint nMaskCode = unchecked((uint)((nCode / 8) + ((nCode & 6) != 0 ? 0 : 1)));
				//// spentness bitmask
				while(nMaskCode > 0)
				{
					byte chAvail = 0;
					stream.ReadWrite(ref chAvail);
					for(uint p = 0 ; p < 8 ; p++)
					{
						bool f = (chAvail & (1 << (int)p)) != 0;
						vAvail.Add(f);
					}
					if(chAvail != 0)
						nMaskCode--;
				}
				// txouts themself
				vout = Enumerable.Range(0, vAvail.Count).Select(_ => new TxOut()).ToList();
				for(uint i = 0 ; i < vAvail.Count ; i++)
				{
					if(vAvail[(int)i])
					{
						TxOutCompressor compressed = new TxOutCompressor();
						stream.ReadWrite(ref compressed);
						vout[(int)i] = compressed.TxOut;
					}
				}
				//// coinbase height
				stream.ReadWriteAsVarInt(ref nHeight);
				Cleanup();
				UpdateValue();
			}
		}
예제 #36
0
        // select a block from the candidate blocks in vSortedByTimestamp, excluding
        // already selected blocks in vSelectedBlocks, and with timestamp up to
        // nSelectionIntervalStop.
        private static bool SelectBlockFromCandidates(ChainedBlock chainIndex, SortedDictionary <uint, uint256> sortedByTimestamp,
                                                      Dictionary <uint256, ChainedBlock> mapSelectedBlocks,
                                                      long nSelectionIntervalStop, ulong nStakeModifierPrev, out ChainedBlock pindexSelected)
        {
            bool    fSelected = false;
            uint256 hashBest  = 0;

            pindexSelected = null;

            foreach (var item in sortedByTimestamp)
            {
                var pindex = chainIndex.FindAncestorOrSelf(item.Value);
                if (pindex == null)
                {
                    return(false);                    // error("SelectBlockFromCandidates: failed to find block index for candidate block %s", item.second.ToString());
                }
                if (fSelected && pindex.Header.Time > nSelectionIntervalStop)
                {
                    break;
                }

                if (mapSelectedBlocks.Keys.Any(key => key == pindex.HashBlock))
                {
                    continue;
                }

                // compute the selection hash by hashing its proof-hash and the
                // previous proof-of-stake modifier
                uint256 hashSelection;
                using (var ms = new MemoryStream())
                {
                    var serializer = new BitcoinStream(ms, true);
                    serializer.ReadWrite(pindex.Header.PosParameters.HashProof);
                    serializer.ReadWrite(nStakeModifierPrev);

                    hashSelection = Hashes.Hash256(ms.ToArray());
                }

                // the selection hash is divided by 2**32 so that proof-of-stake block
                // is always favored over proof-of-work block. this is to preserve
                // the energy efficiency property
                if (pindex.Header.PosParameters.IsProofOfStake())
                {
                    hashSelection >>= 32;
                }

                if (fSelected && hashSelection < hashBest)
                {
                    hashBest       = hashSelection;
                    pindexSelected = pindex;
                }
                else if (!fSelected)
                {
                    fSelected      = true;
                    hashBest       = hashSelection;
                    pindexSelected = pindex;
                }
            }

            //LogPrint("stakemodifier", "SelectBlockFromCandidates: selection hash=%s\n", hashBest.ToString());
            return(fSelected);
        }
예제 #37
0
파일: LockTime.cs 프로젝트: xcrash/NBitcoin
		public void ReadWrite(BitcoinStream stream)
		{
			stream.ReadWrite(ref _value);
		}
예제 #38
0
        public void ReadWrite(BitcoinStream stream)
        {
            lock (cs)
            {
                Check();
                if (!stream.Serializing)
                {
                    Clear();
                }
                stream.ReadWrite(ref nVersion);
                stream.ReadWrite(ref nKeySize);
                if (!stream.Serializing && nKeySize != 32)
                {
                    throw new FormatException("Incorrect keysize in addrman deserialization");
                }
                stream.ReadWrite(ref nKey);
                stream.ReadWrite(ref nNew);
                stream.ReadWrite(ref nTried);

                int nUBuckets = ADDRMAN_NEW_BUCKET_COUNT ^ (1 << 30);
                stream.ReadWrite(ref nUBuckets);
                if (nVersion != 0)
                {
                    nUBuckets ^= (1 << 30);
                }
                if (!stream.Serializing)
                {
                    // Deserialize entries from the new table.
                    for (int n = 0; n < nNew; n++)
                    {
                        AddressInfo info = new AddressInfo();
                        info.ReadWrite(stream);
                        mapInfo.Add(n, info);
                        mapAddr[info.Address.Endpoint.Address] = n;
                        info.nRandomPos = vRandom.Count;
                        vRandom.Add(n);
                        if (nVersion != 1 || nUBuckets != ADDRMAN_NEW_BUCKET_COUNT)
                        {
                            // In case the new table data cannot be used (nVersion unknown, or bucket count wrong),
                            // immediately try to give them a reference based on their primary source address.
                            int nUBucket    = info.GetNewBucket(nKey);
                            int nUBucketPos = info.GetBucketPosition(nKey, true, nUBucket);
                            if (vvNew[nUBucket, nUBucketPos] == -1)
                            {
                                vvNew[nUBucket, nUBucketPos] = n;
                                info.nRefCount++;
                            }
                        }
                    }

                    nIdCount = nNew;

                    // Deserialize entries from the tried table.
                    int nLost = 0;
                    for (int n = 0; n < nTried; n++)
                    {
                        AddressInfo info = new AddressInfo();
                        info.ReadWrite(stream);
                        int nKBucket    = info.GetTriedBucket(nKey);
                        int nKBucketPos = info.GetBucketPosition(nKey, false, nKBucket);
                        if (vvTried[nKBucket, nKBucketPos] == -1)
                        {
                            info.nRandomPos = vRandom.Count;
                            info.fInTried   = true;
                            vRandom.Add(nIdCount);
                            mapInfo[nIdCount] = info;
                            mapAddr[info.Address.Endpoint.Address] = nIdCount;
                            vvTried[nKBucket, nKBucketPos]         = nIdCount;
                            nIdCount++;
                        }
                        else
                        {
                            nLost++;
                        }
                    }

                    nTried -= nLost;

                    // Deserialize positions in the new table (if possible).
                    for (int bucket = 0; bucket < nUBuckets; bucket++)
                    {
                        int nSize = 0;
                        stream.ReadWrite(ref nSize);
                        for (int n = 0; n < nSize; n++)
                        {
                            int nIndex = 0;
                            stream.ReadWrite(ref nIndex);
                            if (nIndex >= 0 && nIndex < nNew)
                            {
                                AddressInfo info        = mapInfo[nIndex];
                                int         nUBucketPos = info.GetBucketPosition(nKey, true, bucket);
                                if (nVersion == 1 && nUBuckets == ADDRMAN_NEW_BUCKET_COUNT && vvNew[bucket, nUBucketPos] == -1 && info.nRefCount < ADDRMAN_NEW_BUCKETS_PER_ADDRESS)
                                {
                                    info.nRefCount++;
                                    vvNew[bucket, nUBucketPos] = nIndex;
                                }
                            }
                        }
                    }

                    // Prune new entries with refcount 0 (as a result of collisions).
                    int nLostUnk = 0;
                    foreach (var kv in mapInfo.ToList())
                    {
                        if (kv.Value.fInTried == false && kv.Value.nRefCount == 0)
                        {
                            Delete(kv.Key);
                            nLostUnk++;
                        }
                    }
                }
                else
                {
                    Dictionary <int, int> mapUnkIds = new Dictionary <int, int>();
                    int nIds = 0;
                    foreach (var kv in mapInfo)
                    {
                        mapUnkIds[kv.Key] = nIds;
                        AddressInfo info = kv.Value;
                        if (info.nRefCount != 0)
                        {
                            assert(nIds != nNew);                             // this means nNew was wrong, oh ow
                            info.ReadWrite(stream);
                            nIds++;
                        }
                    }
                    nIds = 0;
                    foreach (var kv in mapInfo)
                    {
                        AddressInfo info = kv.Value;
                        if (info.fInTried)
                        {
                            assert(nIds != nTried);                             // this means nTried was wrong, oh ow
                            info.ReadWrite(stream);
                            nIds++;
                        }
                    }

                    for (int bucket = 0; bucket < ADDRMAN_NEW_BUCKET_COUNT; bucket++)
                    {
                        int nSize = 0;
                        for (int i = 0; i < ADDRMAN_BUCKET_SIZE; i++)
                        {
                            if (vvNew[bucket, i] != -1)
                            {
                                nSize++;
                            }
                        }
                        stream.ReadWrite(ref nSize);
                        for (int i = 0; i < ADDRMAN_BUCKET_SIZE; i++)
                        {
                            if (vvNew[bucket, i] != -1)
                            {
                                int nIndex = mapUnkIds[vvNew[bucket, i]];
                                stream.ReadWrite(ref nIndex);
                            }
                        }
                    }
                }
                Check();
            }
        }
예제 #39
0
		internal byte[] ReadData(Stream stream)
		{
			uint len = 0;
			BitcoinStream bitStream = new BitcoinStream(stream, false);
			if(Code == 0)
				return new byte[0];

			if((byte)OpcodeType.OP_1 <= (byte)Code && (byte)Code <= (byte)OpcodeType.OP_16)
			{
				return new byte[] { (byte)(Code - OpcodeType.OP_1 + 1) };
			}

			if(Code == OpcodeType.OP_1NEGATE)
			{
				return new byte[] { 0x81 };
			}

			try
			{
				if(0x01 <= (byte)Code && (byte)Code <= 0x4b)
					len = (uint)Code;
				else if(Code == OpcodeType.OP_PUSHDATA1)
					len = bitStream.ReadWrite((byte)0);
				else if(Code == OpcodeType.OP_PUSHDATA2)
					len = bitStream.ReadWrite((ushort)0);
				else if(Code == OpcodeType.OP_PUSHDATA4)
					len = bitStream.ReadWrite((uint)0);
				else
				{
					IsInvalid = true;
					return new byte[0];
				}


				byte[] data = null;

				if(len <= MAX_SCRIPT_ELEMENT_SIZE) //Most of the time
				{
					data = new byte[len];
					var readen = stream.Read(data, 0, data.Length);
					if(readen != data.Length)
					{
						IsInvalid = true;
						return new byte[0];
					}
				}
				else //Mitigate against a big array allocation
				{
					List<byte> bytes = new List<byte>();
					for(int i = 0 ; i < len ; i++)
					{
						var b = stream.ReadByte();
						if(b < 0)
						{
							IsInvalid = true;
							return new byte[0];
						}
						bytes.Add((byte)b);
					}
					data = bytes.ToArray();
				}
				return data;

			}
			catch(EndOfStreamException)
			{
				IsInvalid = true;
				return new byte[0];
			}
		}
예제 #40
0
 public void ReadWrite(BitcoinStream stream)
 {
     stream.ReadWrite(ref _version);
     stream.ReadWrite(ref _height);
     stream.ReadWrite(ref _txOut);
 }
예제 #41
0
 public void ReadWrite(BitcoinStream bitcoinStream)
 {
     bitcoinStream.ReadWrite(ref _bytes);
 }
예제 #42
0
 public override void ReadWriteCore(BitcoinStream stream)
 {
     _uTxOutputs = new UTxOutputs();
     stream.ReadWrite(ref _uTxOutputs);
 }
예제 #43
0
 internal static void StaticWrite(BitcoinStream bs, byte[] bytes)
 {
     VarInt.StaticWrite(bs, (ulong)bytes.Length);
     bs.ReadWrite(ref bytes);
 }
 public override void ReadWriteCore(BitcoinStream stream)
 {
     stream.ReadWrite(ref _FilterType);
     stream.ReadWrite(ref _StopHash);
 }
예제 #45
0
파일: Message.cs 프로젝트: rahhh/FullNodeUI
        public void ReadWrite(BitcoinStream stream)
        {
            if ((this.Payload == null) && stream.Serializing)
            {
                throw new InvalidOperationException("Payload not affected");
            }

            if (stream.Serializing || (!stream.Serializing && !this.skipMagic))
            {
                stream.ReadWrite(ref this.magic);
            }

            stream.ReadWrite(ref this.command);
            int  length      = 0;
            uint checksum    = 0;
            bool hasChecksum = false;

            byte[] payloadBytes = stream.Serializing ? this.GetPayloadBytes(out length) : null;
            length = payloadBytes == null ? 0 : length;
            stream.ReadWrite(ref length);

            if (stream.ProtocolVersion >= ProtocolVersion.MEMPOOL_GD_VERSION)
            {
                if (stream.Serializing)
                {
                    checksum = Hashes.Hash256(payloadBytes, 0, length).GetLow32();
                }

                stream.ReadWrite(ref checksum);
                hasChecksum = true;
            }

            if (stream.Serializing)
            {
                stream.ReadWrite(ref payloadBytes, 0, length);
            }
            else
            {
                // MAX_SIZE 0x02000000 Serialize.h.
                if (length > 0x02000000)
                {
                    throw new FormatException("Message payload too big ( > 0x02000000 bytes)");
                }

                payloadBytes = new byte[length];
                stream.ReadWrite(ref payloadBytes, 0, length);

                if (hasChecksum)
                {
                    if (!VerifyChecksum(checksum, payloadBytes, length))
                    {
                        if (NodeServerTrace.Trace.Switch.ShouldTrace(TraceEventType.Verbose))
                        {
                            NodeServerTrace.Trace.TraceEvent(TraceEventType.Verbose, 0, "Invalid message checksum bytes");
                        }
                        throw new FormatException("Message checksum invalid");
                    }
                }

                BitcoinStream payloadStream = new BitcoinStream(payloadBytes);
                payloadStream.CopyParameters(stream);

                Type payloadType = this.payloadProvider.GetCommandType(this.Command);
                bool unknown     = payloadType == typeof(UnknowPayload);
                if (unknown)
                {
                    NodeServerTrace.Trace.TraceEvent(TraceEventType.Warning, 0, "Unknown command received : " + this.Command);
                }

                object payload = this.payloadObject;
                payloadStream.ReadWrite(payloadType, ref payload);
                if (unknown)
                {
                    ((UnknowPayload)payload).command = this.Command;
                }

                this.Payload = (Payload)payload;
            }
        }
 public override void ReadWriteCore(BitcoinStream stream)
 {
     stream.ReadWrite(ref this.blockId);
     stream.ReadWrite(ref this.transactions);
 }
예제 #47
0
        private async Task <T> SendAsync <T>(HttpMethod method, IBitcoinSerializable body, string relativePath, params object[] parameters) where T : IBitcoinSerializable, new()
        {
            var uri     = GetFullUri(relativePath, parameters);
            var message = new HttpRequestMessage(method, uri);

            if (body != null)
            {
                message.Content = new ByteArrayContent(body.ToBytes());
            }

            var result = await Client.SendAsync(message).ConfigureAwait(false);

            if (!result.IsSuccessStatusCode)
            {
                string error = await result.Content.ReadAsStringAsync().ConfigureAwait(false);

                if (!string.IsNullOrEmpty(error))
                {
                    throw new HttpRequestException(result.StatusCode + ": " + error);
                }
            }
            if (result.StatusCode == HttpStatusCode.NotFound)
            {
                return(default(T));
            }
            if (result.Content?.Headers?.ContentLength > MaxContentLength)
            {
                Logs.Client.LogError($"Content is larger than max content length of {MaxContentLength}bytes for request to: {uri}\nRequest Body: \"{body.ToString()}\"");
                throw new IOException("Content is too big");
            }

            try
            {
                result.EnsureSuccessStatusCode();
            }
            catch (Exception ex)
            {
                Logs.Client.LogError(ex, $"Received HTTP {result.StatusCode} response from: {uri}\nRequest Body: \"{body.ToString()}\"");
                throw ex;
            }

            if (typeof(T) == typeof(byte[]))
            {
                return((T)(object)await result.Content.ReadAsByteArrayAsync().ConfigureAwait(false));
            }
            var str = await result.Content.ReadAsStringAsync().ConfigureAwait(false);

            if (typeof(T) == typeof(string))
            {
                return((T)(object)str);
            }

            var bytes = await result.Content.ReadAsByteArrayAsync().ConfigureAwait(false);

            if (bytes.Length == 0)
            {
                return(default(T));
            }
            var stream = new BitcoinStream(new MemoryStream(bytes), false);

            var data = new T();

            stream.ReadWrite <T>(ref data);
            return(data);
        }
예제 #48
0
        public StandardCycles(Consensus consensus, bool debug)
        {
            _Debug = debug;

            _Shorty = new StandardCycle()
            {
                FriendlyName = "Shorty",
                Consensus    = consensus,
                Denomination = Money.Coins(0.01m),
                Generator    = new OverlappedCycleGenerator()
                {
                    RegistrationOverlap = 1,
                    FirstCycle          = new CycleParameters()
                    {
                        Start = 1,
                        RegistrationDuration = GetBlocksCount(consensus, 20) + 1,
                        SafetyPeriodDuration = GetBlocksCount(consensus, 10),
                        ClientChannelEstablishmentDuration  = GetBlocksCount(consensus, 20),
                        TumblerChannelEstablishmentDuration = GetBlocksCount(consensus, 20),
                        PaymentPhaseDuration   = GetBlocksCount(consensus, 20),
                        TumblerCashoutDuration = GetBlocksCount(consensus, 40),
                        ClientCashoutDuration  = GetBlocksCount(consensus, 20),
                    }
                }
            };

            _Shorty2x = new StandardCycle()
            {
                FriendlyName = "Shorty2x",
                Consensus    = consensus,
                Denomination = Money.Coins(0.02m),
                Generator    = new OverlappedCycleGenerator()
                {
                    RegistrationOverlap = 1,
                    FirstCycle          = new CycleParameters()
                    {
                        Start = 1,
                        RegistrationDuration = GetBlocksCount(consensus, 20 * 2) + 1,
                        SafetyPeriodDuration = GetBlocksCount(consensus, 10),
                        ClientChannelEstablishmentDuration  = GetBlocksCount(consensus, 20 * 4),
                        TumblerChannelEstablishmentDuration = GetBlocksCount(consensus, 20 * 4),
                        PaymentPhaseDuration   = GetBlocksCount(consensus, 20 * 2),
                        TumblerCashoutDuration = GetBlocksCount(consensus, 40 * 2),
                        ClientCashoutDuration  = GetBlocksCount(consensus, 20 * 2),
                    }
                }
            };

            _Kotori = new StandardCycle()
            {
                FriendlyName = "Kotori",
                Consensus    = consensus,
                Denomination = Money.Coins(1.0m),
                Generator    = new OverlappedCycleGenerator()
                {
                    RegistrationOverlap = 1,
                    FirstCycle          = new CycleParameters()
                    {
                        Start = 0,
                        //one cycle per day
                        RegistrationDuration = GetBlocksCount(consensus, 60 * 4) + 1,
                        //make sure tor circuit get renewed
                        SafetyPeriodDuration = GetBlocksCount(consensus, 20),
                        ClientChannelEstablishmentDuration  = GetBlocksCount(consensus, 120),
                        TumblerChannelEstablishmentDuration = GetBlocksCount(consensus, 120),
                        PaymentPhaseDuration   = GetBlocksCount(consensus, 30),
                        TumblerCashoutDuration = GetBlocksCount(consensus, 5 * 60),
                        ClientCashoutDuration  = GetBlocksCount(consensus, 5 * 60)
                    }
                }
            };


            if (!_Debug)
            {
                //Verify that 2 phases are always at least separated by 20 minutes
                foreach (var standard in ToEnumerable())
                {
                    HashSet <uint256> states = new HashSet <uint256>();

                    var start             = standard.Generator.FirstCycle.Start;
                    var periods           = standard.Generator.FirstCycle.GetPeriods();
                    var nonOverlappedPart = periods.Registration.End - periods.Registration.Start - standard.Generator.RegistrationOverlap;
                    var total             = periods.Total.End - periods.Total.Start;


                    var maxOverlapped = Math.Ceiling((decimal)total / (decimal)nonOverlappedPart);

                    for (int i = start;; i += nonOverlappedPart)
                    {
                        var starts =
                            standard.Generator.GetCycles(i)
                            .SelectMany(c =>
                        {
                            var p = c.GetPeriods();
                            return(new[]
                            {
                                p.Registration.Start,
                                p.ClientChannelEstablishment.Start,
                                p.TumblerChannelEstablishment.Start,
                                p.TumblerCashout.Start,
                                p.ClientCashout.Start
                            });
                        }).OrderBy(c => c).ToArray();
                        for (int ii = 1; ii < starts.Length; ii++)
                        {
                            if (starts[ii] - starts[ii - 1] < GetBlocksCount(consensus, 20))
                            {
                                throw new InvalidOperationException("A standard cycle generator generates cycles which overlap too much");
                            }
                        }

                        //Check if it is a we already checked such state module total
                        for (int ii = 0; ii < starts.Length; ii++)
                        {
                            starts[ii] = starts[ii] % total;
                        }
                        MemoryStream  ms = new MemoryStream();
                        BitcoinStream bs = new BitcoinStream(ms, true);
                        bs.ReadWrite(ref starts);
                        if (!states.Add(Hashes.Hash256(ms.ToArray())))
                        {
                            break;
                        }
                    }
                }
            }
        }
예제 #49
0
        public byte[] UntrustedHashTransactionInputFinalizeFull(IEnumerable<TxOut> outputs)
        {
            using(Transport.Lock())
            {
                byte[] result = null;
                int offset = 0;
                byte[] response = null;
                var ms = new MemoryStream();
                BitcoinStream bs = new BitcoinStream(ms, true);
                var list = outputs.ToList();
                bs.ReadWrite<List<TxOut>, TxOut>(ref list);
                var data = ms.ToArray();

                while(offset < data.Length)
                {
                    int blockLength = ((data.Length - offset) > 255 ? 255 : data.Length - offset);
                    byte[] apdu = new byte[blockLength + 5];
                    apdu[0] = LedgerWalletConstants.LedgerWallet_CLA;
                    apdu[1] = LedgerWalletConstants.LedgerWallet_INS_HASH_INPUT_FINALIZE_FULL;
                    apdu[2] = ((offset + blockLength) == data.Length ? (byte)0x80 : (byte)0x00);
                    apdu[3] = (byte)0x00;
                    apdu[4] = (byte)(blockLength);
                    Array.Copy(data, offset, apdu, 5, blockLength);
                    response = ExchangeApdu(apdu, OK);
                    offset += blockLength;
                }
                result = response; //convertResponseToOutput(response);
                if(result == null)
                {
                    throw new LedgerWalletException("Unsupported user confirmation method");
                }
                return result;
            }
        }
예제 #50
0
 public void ReadWrite(BitcoinStream stream)
 {
     stream.ReadWriteAsVarInt(ref _Index);
     stream.ReadWrite(ref _Asset);
 }
예제 #51
0
 public override void ReadWriteCore(BitcoinStream stream)
 {
     stream.ReadWrite(ref version);
     stream.ReadWrite(ref blockLocators);
     stream.ReadWrite(ref hashStop);
 }
        private static ulong ReadLEB128(BitcoinStream stream)
        {
            ulong value = 0;

            value = stream.ReadWrite((byte)0);
            if ((value & 128uL) == 0uL)
            {
                return(value);
            }
            value &= 127uL;
            ulong chunk = stream.ReadWrite((byte)0);

            value |= (chunk & 127uL) << 7;
            if ((chunk & 128uL) == 0uL)
            {
                return(value);
            }
            chunk  = stream.ReadWrite((byte)0);
            value |= (chunk & 127uL) << 14;
            if ((chunk & 128uL) == 0uL)
            {
                return(value);
            }
            chunk  = stream.ReadWrite((byte)0);
            value |= (chunk & 127uL) << 21;
            if ((chunk & 128uL) == 0uL)
            {
                return(value);
            }
            chunk  = stream.ReadWrite((byte)0);
            value |= (chunk & 127uL) << 28;
            if ((chunk & 128uL) == 0uL)
            {
                return(value);
            }
            chunk  = stream.ReadWrite((byte)0);
            value |= (chunk & 127uL) << 35;
            if ((chunk & 128uL) == 0uL)
            {
                return(value);
            }
            chunk  = stream.ReadWrite((byte)0);
            value |= (chunk & 127uL) << 42;
            if ((chunk & 128uL) == 0uL)
            {
                return(value);
            }
            chunk  = stream.ReadWrite((byte)0);
            value |= (chunk & 127uL) << 49;
            if ((chunk & 128uL) == 0uL)
            {
                return(value);
            }
            chunk  = stream.ReadWrite((byte)0);
            value |= (chunk & 127uL) << 56;
            if ((chunk & 128uL) == 0uL)
            {
                return(value);
            }
            chunk  = stream.ReadWrite((byte)0);
            value |= chunk << 63;
            if ((chunk & 18446744073709551614uL) != 0uL)
            {
                throw new FormatException("Invalid LEB128 number");
            }
            return(value);
        }
예제 #53
0
파일: Key.cs 프로젝트: woutersmit/NBitcoin
		public void ReadWrite(BitcoinStream stream)
		{
			stream.ReadWrite(ref vch);
			if(!stream.Serializing)
			{
				_ECKey = new ECKey(vch, true);
			}
		}
예제 #54
0
 public void ReadWrite(BitcoinStream stream)
 {
     stream.ReadWrite(ref vtxundo);
 }
예제 #55
0
		//https://en.bitcoin.it/wiki/OP_CHECKSIG
		public uint256 SignatureHash(Transaction txTo, int nIn, SigHash nHashType)
		{
			if(nIn >= txTo.Inputs.Count)
			{
				Utils.log("ERROR: SignatureHash() : nIn=" + nIn + " out of range\n");
				return uint256.One;
			}

			// Check for invalid use of SIGHASH_SINGLE
			if(nHashType == SigHash.Single)
			{
				if(nIn >= txTo.Outputs.Count)
				{
					Utils.log("ERROR: SignatureHash() : nOut=" + nIn + " out of range\n");
					return uint256.One;
				}
			}

			var scriptCopy = new Script(_Script);
			scriptCopy.FindAndDelete(OpcodeType.OP_CODESEPARATOR);

			var txCopy = new Transaction(txTo.ToBytes());

			//Set all TxIn script to empty string
			foreach(var txin in txCopy.Inputs)
			{
				txin.ScriptSig = new Script();
			}
			//Copy subscript into the txin script you are checking
			txCopy.Inputs[nIn].ScriptSig = scriptCopy;

			var hashType = nHashType & (SigHash)31;
			if(hashType == SigHash.None)
			{
				//The output of txCopy is set to a vector of zero size.
				txCopy.Outputs.Clear();

				//All other inputs aside from the current input in txCopy have their nSequence index set to zero
				foreach(var input in txCopy.Inputs.Where((x, i) => i != nIn))
					input.Sequence = 0;
			}
			else if(hashType == SigHash.Single)
			{
				//The output of txCopy is resized to the size of the current input index+1.
				txCopy.Outputs.RemoveRange(nIn + 1, txCopy.Outputs.Count - (nIn + 1));
				//All other txCopy outputs aside from the output that is the same as the current input index are set to a blank script and a value of (long) -1.
				for(var i = 0 ; i < txCopy.Outputs.Count ; i++)
				{
					if(i == nIn)
						continue;
					txCopy.Outputs[i] = new TxOut();
				}
				//All other txCopy inputs aside from the current input are set to have an nSequence index of zero.
				foreach(var input in txCopy.Inputs.Where((x, i) => i != nIn))
					input.Sequence = 0;
			}


			if((nHashType & SigHash.AnyoneCanPay) != 0)
			{
				//The txCopy input vector is resized to a length of one.
				var script = txCopy.Inputs[nIn];
				txCopy.Inputs.Clear();
				txCopy.Inputs.Add(script);
				//The subScript (lead in by its length as a var-integer encoded!) is set as the first and only member of this vector.
				txCopy.Inputs[0].ScriptSig = scriptCopy;
			}


			//Serialize TxCopy, append 4 byte hashtypecode
			var ms = new MemoryStream();
			var bitcoinStream = new BitcoinStream(ms, true);
			txCopy.ReadWrite(bitcoinStream);
			bitcoinStream.ReadWrite((uint)nHashType);

			var hashed = ms.ToArray();
			return Hashes.Hash256(hashed);
		}
예제 #56
0
 public void ReadWrite(BitcoinStream stream)
 {
     stream.ReadWrite(ref vprevout);
 }
예제 #57
0
		private void PushDataToStream(byte[] data, Stream result)
		{
			var bitStream = new BitcoinStream(result, true);

			if(Code == OpcodeType.OP_0)
			{
				//OP_0 already pushed
				return;
			}

			if(OpcodeType.OP_1 <= Code && Code <= OpcodeType.OP_16)
			{
				//OP_1 to OP_16 already pushed
				return;
			}
			if(Code == OpcodeType.OP_1NEGATE)
			{
				//OP_1Negate already pushed
				return;
			}

			if(0x01 <= (byte)Code && (byte)Code <= 0x4b)
			{
				//Data length already pushed
			}
			else if(Code == OpcodeType.OP_PUSHDATA1)
			{
				bitStream.ReadWrite((byte)data.Length);
			}
			else if(Code == OpcodeType.OP_PUSHDATA2)
			{
				bitStream.ReadWrite((ushort)data.Length);
			}
			else if(Code == OpcodeType.OP_PUSHDATA4)
			{
				bitStream.ReadWrite((uint)data.Length);
			}
			else
				throw new NotSupportedException("Data length should not be bigger than 0xFFFFFFFF");
			result.Write(data, 0, data.Length);
		}
예제 #58
0
 public override void ReadWriteCore(BitcoinStream stream)
 {
     stream.ReadWrite(ref inventory);
 }
예제 #59
0
            public override uint256 GetSignatureHash(Script scriptCode, int nIn, SigHash nHashType, TxOut spentOutput, HashVersion sigversion, PrecomputedTransactionData precomputedTransactionData)
            {
                if (sigversion == HashVersion.WitnessV0)
                {
                    if (spentOutput?.Value == null || spentOutput.Value == TxOut.NullMoney)
                    {
                        throw new ArgumentException("The output being signed with the amount must be provided", nameof(spentOutput));
                    }
                    uint256 hashPrevouts = uint256.Zero;
                    uint256 hashSequence = uint256.Zero;
                    uint256 hashOutputs  = uint256.Zero;

                    if ((nHashType & SigHash.AnyoneCanPay) == 0)
                    {
                        hashPrevouts = precomputedTransactionData == null?
                                       GetHashPrevouts() : precomputedTransactionData.HashPrevouts;
                    }

                    if ((nHashType & SigHash.AnyoneCanPay) == 0 && ((uint)nHashType & 0x1f) != (uint)SigHash.Single && ((uint)nHashType & 0x1f) != (uint)SigHash.None)
                    {
                        hashSequence = precomputedTransactionData == null?
                                       GetHashSequence() : precomputedTransactionData.HashSequence;
                    }

                    if (((uint)nHashType & 0x1f) != (uint)SigHash.Single && ((uint)nHashType & 0x1f) != (uint)SigHash.None)
                    {
                        hashOutputs = precomputedTransactionData == null?
                                      GetHashOutputs() : precomputedTransactionData.HashOutputs;
                    }
                    else if (((uint)nHashType & 0x1f) == (uint)SigHash.Single && nIn < this.Outputs.Count)
                    {
                        BitcoinStream ss = CreateHashWriter(sigversion);
                        ss.ReadWrite(this.Outputs[nIn]);
                        hashOutputs = GetHash(ss);
                    }

                    BitcoinStream sss = CreateHashWriter(sigversion);
                    // Version
                    sss.ReadWrite(this.Version);
                    sss.ReadWrite(this.Time);                     // Neblio Timestamp!!!
                    // Input prevouts/nSequence (none/all, depending on flags)
                    sss.ReadWrite(hashPrevouts);
                    sss.ReadWrite(hashSequence);
                    // The input being signed (replacing the scriptSig with scriptCode + amount)
                    // The prevout may already be contained in hashPrevout, and the nSequence
                    // may already be contain in hashSequence.
                    sss.ReadWrite(Inputs[nIn].PrevOut);
                    sss.ReadWrite(scriptCode);
                    sss.ReadWrite(spentOutput.Value.Satoshi);
                    sss.ReadWrite((uint)Inputs[nIn].Sequence);
                    // Outputs (none/one/all, depending on flags)
                    sss.ReadWrite(hashOutputs);
                    // Locktime
                    sss.ReadWriteStruct(LockTime);
                    // Sighash type
                    sss.ReadWrite((uint)nHashType);

                    return(GetHash(sss));
                }

                bool fAnyoneCanPay = (nHashType & SigHash.AnyoneCanPay) != 0;
                bool fHashSingle   = ((byte)nHashType & 0x1f) == (byte)SigHash.Single;
                bool fHashNone     = ((byte)nHashType & 0x1f) == (byte)SigHash.None;

                if (nIn >= Inputs.Count)
                {
                    return(uint256.One);
                }
                if (fHashSingle)
                {
                    if (nIn >= Outputs.Count)
                    {
                        return(uint256.One);
                    }
                }

                var stream = CreateHashWriter(sigversion);

                stream.ReadWrite(Version);
                stream.ReadWrite(this.Time);                 // Neblio Timestamp!!!
                uint nInputs = (uint)(fAnyoneCanPay ? 1 : Inputs.Count);

                stream.ReadWriteAsVarInt(ref nInputs);
                for (int nInput = 0; nInput < nInputs; nInput++)
                {
                    if (fAnyoneCanPay)
                    {
                        nInput = nIn;
                    }
                    stream.ReadWrite(Inputs[nInput].PrevOut);
                    if (nInput != nIn)
                    {
                        stream.ReadWrite(Script.Empty);
                    }
                    else
                    {
                        WriteScriptCode(stream, scriptCode);
                    }

                    if (nInput != nIn && (fHashSingle || fHashNone))
                    {
                        stream.ReadWrite((uint)0);
                    }
                    else
                    {
                        stream.ReadWrite((uint)Inputs[nInput].Sequence);
                    }
                }

                uint nOutputs = (uint)(fHashNone ? 0 : (fHashSingle ? nIn + 1 : Outputs.Count));

                stream.ReadWriteAsVarInt(ref nOutputs);
                for (int nOutput = 0; nOutput < nOutputs; nOutput++)
                {
                    if (fHashSingle && nOutput != nIn)
                    {
                        this.Outputs.CreateNewTxOut().ReadWrite(stream);
                    }
                    else
                    {
                        Outputs[nOutput].ReadWrite(stream);
                    }
                }

                stream.ReadWriteStruct(LockTime);
                stream.ReadWrite((uint)nHashType);
                return(GetHash(stream));
            }
예제 #60
0
        // IBitcoinSerializable Members

        public override void ReadWriteCore(BitcoinStream stream)
        {
            stream.ReadWrite(ref _addrList);
        }